2013-02-22 8 views
6

Pracuję z danymi .csv, które zostały wyeksportowane z Teradata. Kilka kolumn było pierwotnie znacznikami czasowymi ze strefami czasowymi, więc po załadowaniu pliku .csv w R chciałbym przekonwertować te kolumny (które są ładowane jako łańcuchy) na POSIXlt lub POSIXct. Używam strptime, ale format strefy czasowej z pliku .csv nie jest zgodny z oczekiwaniami, które oczekiwałby strptime. Na przykład oczekuje on od -0400, ale plik .csv ma ​​format -04:00, w którym dwukropek oddziela godziny i minuty.Użycie strptime% z ze specjalnym formatem strefy czasowej

Mogę usunąć dwukropek, ale jest to dodatkowy krok i komplikacja, której chciałbym uniknąć, jeśli to możliwe. Czy istnieje sposób, aby powiedzieć strptime, aby użyć innego formatu strefy czasowej (%z)?

Oto przykład:

## Example data: 
x <- c("2011-10-12 22:17:13.860746-04:00", "2011-10-12 22:17:13.860746+00:00") 
format <- "%Y-%m-%d %H:%M:%OS%z" 

## Doesn't work: 
strptime(x,format) 
## [1] NA NA 

## Ignores the timezone: 
as.POSIXct(x) 
## [1] "2011-10-12 22:17:13 EDT" "2011-10-12 22:17:13 EDT" 

## Remove the last colon: 
x2 <- gsub("(.*):", "\\1", x) 
x2 
## [1] "2011-10-12 22:17:13.860746-0400" "2011-10-12 22:17:13.860746+0000" 

## This works, but requires extra processing (removing the colon) 
strptime(x2,format) 
## [1] "2011-10-12 22:17:13" "2011-10-12 18:17:13" 

Więc szukam, aby osiągnąć ten ostatni wynik używając coś jak strptime(x,"%Y-%m-%d %H:%M:%OS%zz"), gdzie %zz jest zwyczaj wyrażenie dla strefy czasowej, która rozpoznaje formatu na -04:00. Lub %zH:%zM może być jeszcze lepiej.

Jeśli nie jest to możliwe, czy ktoś ma elastyczną/elastyczną funkcję do konwersji ciągów (różnych formatów) do dat dla wielu kolumn danych data.frame/data.table?

Odpowiedz

3

Okazuje się lubridate może obsługiwać format:

library(lubridate) 
ymd_hms(x) 
## [1] "2011-10-13 02:17:13 UTC" "2011-10-12 22:17:13 UTC" 

Lub, aby wyświetlić w lokalnej strefy czasowej:

with_tz(ymd_hms(x)) 
## [1] "2011-10-12 22:17:13 EDT" "2011-10-12 18:17:13 EDT" 

większej elastyczności (nadal używa lubridate):

parse_date_time(x, "%Y-%m-%d %H:%M:%OS%z") 

Dla szybszej prędkości (między lubridate opcje):

lubridate:::.strptime(x, "%Y-%m-%d %H:%M:%OS%OO") 

Timings:

microbenchmark(
    ymd_hms(x), 
    parse_date_time(x, "%Y-%m-%d %H:%M:%OS%z"), 
    lubridate:::.strptime(x, "%Y-%m-%d %H:%M:%OS%OO"), 
    strptime(gsub("(.*):", "\\1", x), format) 
) 

## Unit: microseconds 
##            expr  min  lq  mean median  uq  max neval 
##           ymd_hms(x) 1523.819 1578.495 1715.14577 1629.5385 1744.3695 2850.393 100 
##   parse_date_time(x, "%Y-%m-%d %H:%M:%OS%z") 1108.676 1150.633 1273.77301 1190.3315 1264.8050 5947.204 100 
## lubridate:::.strptime(x, "%Y-%m-%d %H:%M:%OS%OO") 89.838 103.390 112.45338 107.8425 115.2265 216.512 100 
##  strptime(gsub("(.*):", "\\\\1", x), format) 46.716 58.294 71.90934 69.9415 86.5860 105.044 100 
2

Właśnie natknąłem się na to pytanie, próbując osiągnąć to samo.

Jedyną rzeczą, którą udało mi się naprawić, jest użycie regex do usunięcia dwukropka, jak już wspomniano. Możesz nieco zaostrzyć regex, aby uniknąć błędów w zastępstwie.

x2 <- gsub('^([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]+[+-][0-9]{2}):([0-9]{2})$', 
      '\\1\\2', 
      x) 
# [1] "2011-10-12 22:17:13.860746-0400" "2011-10-12 22:17:13.860746+0000" 
+4

Jest 2016, a świat wciąż mając do czynienia z tym ... – sehe

Powiązane problemy