Быстрое и эффективное преобразование года, жюльена и времени в POSIXct из нескольких столбцов в базовом R - PullRequest
0 голосов
/ 07 мая 2020

У меня есть много больших фреймов данных (+500 000 строк), которые приходят ко мне с информацией о дате и времени, хранящейся в нескольких столбцах. Вместо формата ММ / ДД / ГГГГ в одном столбце указан год, в следующем - июльский календарный день, а в третьем - время. Данные структурированы следующим образом:

df<-data.frame(YEAR = sample(2000:2020,10000, replace=T), 
           JULIEN = sample(1:365,10000,replace=T),
           Time = sample(0:59,10000,replace = T),
           dataVar1 = runif(10000,1.0,10.0),
           dataVar2 = runif(10000,20.0,100.0))

До сих пор я обходился с этим:

timeR<-vector()
for (i in 1:dim(df)[1]){
currentTime<-paste(as.Date(df$JULIEN[i], origin=paste(df$YEAR[i]-1,"-12-31", sep = "")),formatC(df$Time[i], width = 4, format = "d", flag = "0"))
timeR<-c(timeR,currentTime)
}
df<-cbind(timeR,df[, ! names(df) %in% c("YEAR","JULIEN","Time")])
df$timeR<-as.POSIXct(df$timeR,format = "%Y-%m-%d %H%M", tz = "EST")
rm(timeR,i,currentTime)

, но это занимает очень много времени. Есть идеи, как сделать это быстрее? Спасибо.

1 Ответ

0 голосов
/ 07 мая 2020

paste и as.Date векторизованы

v1 <- as.Date(df$JULIEN, origin = paste0(df$YEAR-1,"-12-31"))
currentTime <- paste(v1, formatC(df$Time, width = 4, format = "d", flag = "0"))

Тесты

system.time({
 timeR<-vector()
 for (i in 1:dim(df)[1]){
  currentTime<-paste(as.Date(df$JULIEN[i], origin=paste(df$YEAR[i]-1,"-12-31", sep = "")),formatC(df$Time[i], width = 4, format = "d", flag = "0"))
  timeR<-c(timeR,currentTime)
 }})
#   user  system elapsed #
#  1.300   0.061   1.366 

system.time({
 v1 <- as.Date(df$JULIEN, origin = paste0(df$YEAR-1,"-12-31"))
 currentTime <- paste(v1, formatC(df$Time, width = 4, format = "d", flag = "0"))
 })
#  user  system elapsed 
#  0.076   0.004   0.080 
...