使用 apply 函数和 data.table 结合,为什么会很慢?

3
我正在使用data.table包,我使用了以下代码:
dt$date<- as.POSIXct(dt$date, tz="GMT")      (I know I can use fastPOSIXct)
2009-08-07 06:00:14
2009-08-07 06:00:15
2009-08-07 06:00:16 
2009-08-07 06:00:24

我希望更改时区(有很多个时区),并提取小时数。假设我想使用apply函数:

f <- function(x) {
  SydneyTime<-format(x["date"], format = "%Y-%m-%d %H:%M:%OS", tz = "Australia/Sydney")
  Sy<-hour(SydneyTime)
  return(Sy)
}

mydata$SyHour <- apply(dt, 1, f)

这太慢了,我有什么遗漏吗?我不想保留SydneyTime的副本。

谢谢。


6
apply函数将数据表强制转换为矩阵,你将失去所有数据表的特性。 - Roland
1个回答

4

您不需要复制任何内容。format.Date是矢量化的,因此您可以使用:=data.table中创建一个新列,使用原始列中的数据。这里是一个小的可重现示例:

require( data.table )
#  Seconds in the day
n <- 86400

#  Make some data
DT <- data.table( Date = as.POSIXct( Sys.time()+seq(0,2*n,by=n) , tz = "GMT") )
#                  Date
#1: 2013-08-28 21:17:10
#2: 2013-08-29 21:17:10
#3: 2013-08-30 21:17:10

#  Change the TZ
DT[ , Date2:=format( Date , tz = "Australia/Sydney")]
#                  Date               Date2
#1: 2013-08-28 21:17:10 2013-08-29 06:17:10
#2: 2013-08-29 21:17:10 2013-08-30 06:17:10
#3: 2013-08-30 21:17:10 2013-08-31 06:17:10

编辑下面的评论

lapply旨在与data.table逐列一起使用。要原地修改列Date,可以这样做:

DT[ , lapply( .SD , format , tz = "Australia/Sydney" ) ]

但在使用这个方法处理真实数据前,请确保您已经了解了.SD.SDcols的含义。


  1. 我假设 SydneyTime <- ... 和 := 背后的故事不同,这就是它们最终速度不同的原因,对吗?
  2. 你如何使用 apply 函数族来实现这个功能?谢谢!
- Sahand
4
  1. 是的。 := 是一个 data.table 的函数。通过输入 ?data.table::\:=``来了解它。
  2. 我不明白为什么你 想要 在一个 data.table 上使用 apply,因为它并不是专门为此设计的。
- Simon O'Hanlon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接