我有一个data.table,我想按组提取最后10,000行。不幸的是,根据所采用的方法,我得到的结果不一致,因此显然我无法理解全部情况。我对自己的每种方法都有疑问。
数据的结构方式使得我有一组列希望分组,在这些列中我要获取与最后10,000个POSIXct时间戳相对应的条目(如果存在的话...否则返回全部)。通过分组列和时间戳的组合将条目定义为唯一,即使还有其他几个数据列也是如此。在下面的示例中,我的时间戳列位于ts中,而keycol1和keycol2是我要分组的字段。 DT有2,809,108个条目。
setkey(DT,keycol1,keycol2,ts)
DT[DT[,.I[.N-10000:.N], by=c("keycol1","keycol2")]$V1]
返回1,181,256个条目。没有发出警告或错误。我担心的是当该组的.N-10000 <1时会发生什么?当我执行DT[-10:10]
时,出现以下错误。
[.data.table
(DT,-10:10)中的错误:i的项目1为-10,项目 12是1。不能混合使用正负。
使我相信.I[.N-10000:.N]
可能无法正常工作。
如果我改为尝试将时间戳向后排序,然后使用Jaap在他对this question的回答中描述的策略
DT[DT[order(-ts),.I[1:10000], by=c("keycol1","keycol2")]$V1],nomatch=NULL]
返回3,810,000个条目,其中一些全为NA,表明不遵守nomatch参数(nomatch=0
返回相同)。链接[!is.na(ts)]
告诉我它返回1,972,166个有效条目,这比以前的“解决方案”还多。但是,.I
的值是否与原始DT或反向排序(组内)DT的行号相对应?那么,外部选择是返回真正的匹配结果,还是实际上会导致每个组的前10000个条目,而不是最后10000个?
好吧,要解决此问题,我可以让钥匙本身向后工作吗?
setkey(DT,keycol1,keycol2,ts)
setorder(DT,keycol1,keycol2,-ts)
key(DT)
NULL
setkey(DT,keycol1,keycol2,-ts)
setkeyv(x,cols,详细=详细,物理=物理)中的错误: 某些列不在data.table中:-ts
那将是一个否定。
可以通过使用.SD
而不是.I
来解决此问题吗?
DT[
DT[order(-ts), .SD[1:10000], by=c("keycol1","keycol2")],
nomatch=0, on=c("keycol1","keycol2","ts")
]
返回1,972,166个条目。尽管我相当确信这些条目是我想要的条目,但这也会导致列的重复,而不是键或时间戳的一部分(例如i.A,i.B等)。我认为,这些是与带有.I[1:10000]
的{{1}}示例相同的条目,就像我存储每个条目一样,删除order(-ts)
方法中多余的列,然后对每个对象执行一次.SD
,然后执行setkey(resultA, keycol1,keycol2,ts)
返回
是
相关线程:
Throw away first and last n rows