我是一名新手,对于data.table“场景”不太熟悉,所以如果我的问题过于简单,请谅解。我通常需要应用一些分析或对按唯一ID分组的数据进行子集操作。通常,每个唯一ID有大约1,000行数据,大约有30个唯一ID。因此,我被建议改用data.table而不是尝试弄清楚lapply、sapply或plyr包。
这里是我数据类型的样本
structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L,
3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), dt = structure(c(1138366975,
1138370472, 1138374064, 1138377669, 1138381264, 1138384873, 1138388503,
1138399312, 1138402842, 1138406507, 1138413700, 1138417261, 1138420848,
1138424444, 1138428071, 1138431695, 1138435287, 1138438938, 1138442428,
1138446098), class = c("POSIXct", "POSIXt"), tzone = "GMT")), .Names = c("ID",
"dt"), row.names = c(NA, -20L), class = "data.frame")
我将把这转化为一个数据表。
X = data.table(test)
将我的“key”设置为个体
setkey(X,ID)
那么目标是计算时间差,以小时为单位(希望这将是容易的),因此需要将Time2-Time1相减来得出每个人(在此情况下为ID)在连续位置之间所花费的小时和分钟。
X[, diff:=c(NA,diff(dt)),by = ID]
这里的diff命令计算的是分钟,但我希望以最有效的方式将其转换/四舍五入为小时,并仍然将值保持为POSIX或时间对象。我知道我可以创建另一列并将diff除以60。但我希望有一种方法只需在某个地方键入“小时”或“分钟”或其他内容即可。因为我不理解data.table如何处理时间。
我尝试使用for循环和difftime命令在data.frame中完成这个操作,但它太繁琐了,将数据链接回原始数据框对我来说很困惑,因为我不精通for循环。
一旦我将数据转换为小时,我想选择仅相隔0.5小时、4小时和12小时的数据,但我还没有找到在data.table中如何实现这一点。
X$timediff<-X[ , c( NA_character_ , difftime( tail( dt , -1 ) , head( dt , -1 ) , units = "hours" ) ) , by = ID ]
的内容,但出现了错误消息,并且新的信息列更像是与1个变量相关联的3个新元素的列表。非常令人困惑。 - Kerrydata.frame
和data.table
的语法。不要使用X$timediff <- ...
。正确的方法是使用X[ , c( NA_character_ , ...
。运行后,查看X
,你会发现一个新的列。NA_character_
只是NA
的字符版本,需要将结果强制转换为character
向量,否则data.table
会抱怨数据类型不匹配(数字和字符)。 - Simon O'Hanlonhead
和tail
...试试吧!例如:x <- 1:5; head( x , -1 ); tail( x , -1 )
。第一个函数返回向量中除了最后一个元素的所有元素,而使用-1
的tail
函数则返回一个没有第一个元素的向量,因此我们可以从紧接着它之前的时间中减去后续时间。(尝试一下tail(x,-1) - head(x,-1)
,它等同于2:5 - 1:4
,所以结果是1 1 1 1
。 - Simon O'Hanlondata.table
中。希望现在清楚了。 - Simon O'Hanlon