在R中,我有一个大的data.table。对于每一行,我想要计算具有类似x1值(+/- 一些容差tol)的行数。我可以通过adply来实现这个目标,但速度太慢了。看起来像是data.table非常擅长的事情 - 实际上,我已经在部分计算中使用了data.table。
是否有一种完全使用data.table来完成这项任务的方法?下面是一个示例:
显然,@eddi和@Arun的解决方案比我的快得多。现在我只需要尝试理解“rolls”的含义。
是否有一种完全使用data.table来完成这项任务的方法?下面是一个示例:
library(data.table)
library(plyr)
my.df = data.table(x1 = 1:1000,
x2 = 4:1003)
tol = 3
adply(my.df, 1, function(df) my.df[x1 > (df$x1 - tol) & x1 < (df$x1 + tol), .N])
结果:
x1 x2 V1
1: 1 4 3
2: 2 5 4
3: 3 6 5
4: 4 7 5
5: 5 8 5
---
996: 996 999 5
997: 997 1000 5
998: 998 1001 5
999: 999 1002 4
1000: 1000 1003 3
更新:
这里是一个样本数据集,更接近于我的真实数据:
set.seed(10)
x = seq(1,100000000,100000)
x = x + sample(1:50000, length(x), replace=T)
x2 = x + sample(1:50000, length(x), replace=T)
my.df = data.table(x1 = x,
x2 = x2)
setkey(my.df,x1)
tol = 100000
og = function(my.df) {
adply(my.df, 1, function(df) my.df[x1 > (df$x1 - tol) & x1 < (df$x1 + tol), .N])
}
microbenchmark(r_ed <- ed(copy(my.df)),
r_ar <- ar(copy(my.df)),
r_og <- og(copy(my.df)),
times = 1)
Unit: milliseconds
expr min lq median uq max neval
r_ed <- ed(copy(my.df)) 8.553137 8.553137 8.553137 8.553137 8.553137 1
r_ar <- ar(copy(my.df)) 10.229438 10.229438 10.229438 10.229438 10.229438 1
r_og <- og(copy(my.df)) 1424.472844 1424.472844 1424.472844 1424.472844 1424.472844 1
显然,@eddi和@Arun的解决方案比我的快得多。现在我只需要尝试理解“rolls”的含义。
set.seed(10)
x = seq(1,100000000,100000)
x = x + sample(1:50000, length(x), replace=T)
x2 = x + sample(1:50000, length(x), replace=T)
my.df = data.table(x1 = x, x2 = x2)
setkey(my.df,x1)
tol = 100000
- benjaminpmax(nrow(my.df)...)
... 它并不是必要的。修改应该可以正常工作。 - Arun