【发布时间】:2016-11-02 15:34:40
【问题描述】:
我想知道每个变量在每个组中更改了多少次,然后将结果添加到所有组。
我是这样找到的:
mi[,lapply(.SD, function(x) sum(x != shift(x),
na.rm=T) ), by = ID][,-1][,lapply(.SD,sum, na.rm=T)]
它有效,它产生了正确的结果,但在我的大型数据表中它真的很慢。 我想在同一个 lapply 中执行这两个操作(或者更快更紧凑的操作),但是第一个是按组完成的,第二个不是。
可以用更简单的方式编写(可能并非总是如此)
mi[,lapply(.SD, function(x) sum(x != shift(x),
na.rm=T) )] [,-1]-mi[,length(unique(ID))]+1
但它仍然很慢并且需要大量内存。
还有什么想法吗?
我也尝试过使用 diffs 而不是 shift,但它变得更加困难。
这里有一个虚拟示例:
mi <- data.table(ID=rep(1:3,each=4) , year=rep(1:4, times=3),
VREP=rep(1:3,each=4) , VDI=rep(1:4, times=3), RAN=sample(12))
mi <- rbind(mi, data.table(4,1,1,1,0), use.names=F)
基准测试的重要示例
mi <- as.data.table(matrix(sample(0:100,10000000,
replace=T), nrow=100000, ncol=100))
mi[,ID := rep(1:1000,each=100)]
我的问题是真正的数据集要大得多,它在内存大小的限制中,然后我将 R 配置为能够使用页面文件使用更多内存,这会使许多操作变慢。 我知道我可以拆分文件并再次加入它,但有时这会使事情变得更加困难或某些操作不可拆分。
【问题讨论】:
-
除非我遗漏了什么,按“ID”排序后,您可以计算值变化与 id 不变的次数;
id = mi$ID[-1] == mi$ID[-nrow(mi)]; sapply(mi, function(x) sum((x[-1] != x[-length(x)]) & id)) -
很抱歉,您的方法比我的第一种方法慢两倍,比第二种方法慢四倍。
-
需要基准和适当大的示例(编写为
n的函数)... -
有了新的 data.table 我的 benhcmkark 是:method1 1.35sec,method2 0.092sec,alexis 0.30sec
-
@skan:从你的两个答案中,我不得不删除
[, -1],因为否则我无法让它工作——它似乎与"[.data.table"的工作方式有关,除非我有一个过时的版本。除此之外,您的“method2”确实更快,但是(至少对于您的大型数据集而言)它似乎没有返回与“method1”和我的相同的结果(返回相同的结果)。
标签: r data.table