![](/img/trans.png)
[英]how to apply varying gsub pattern (variable function) to each row of data.table in R
[英]How to effectively determine the maximum difference between the variable value in each row and same variable subsequent row values in data.table in R
在R中的data.table中,确定每一行的值(X)与组(Y)中相同变量(X)的后续值之间的最大正差异的最有效方法是什么?
例:
set.seed(1)
dt <- data.table(X = sample(100:200, 500455, replace = TRUE),
Y = unlist(sapply(10:1000, function(x) rep(x, x))))
这是我认为无效和缓慢的解决方案:
dt[, max_diff := vapply(1:.N, function(x) max(X[x:.N] - X[x]), numeric(1)), by = Y]
head(dt, 21)
X Y max_diff
1: 126 10 69
2: 137 10 58
3: 157 10 38
4: 191 10 4
5: 120 10 75
6: 190 10 5
7: 195 10 0
8: 166 10 0
9: 163 10 0
10: 106 10 0
11: 120 11 80
12: 117 11 83
13: 169 11 31
14: 138 11 62
15: 177 11 23
16: 150 11 50
17: 172 11 28
18: 200 11 0
19: 138 11 56
20: 178 11 16
21: 194 11 0
如果您可以建议有效(更快)的解决方案?
这是一个快速约20倍的dplyr解决方案,并获得相同的结果。 我认为data.table等价物会更快。 (编辑:见底 - 这是!)
加速来自减少需要执行的比较次数。 最大差异将始终与组中最大的剩余数字相对应,因此首先识别该数字并且每行仅进行一次减法更快。
首先,原始解决方案在我的机器上大约需要4秒钟:
tictoc::tic("OP data.table")
dt[, max_diff := vapply(1:.N, function(x) max(X[x:.N] - X[x]), numeric(1)), by = Y]
tictoc::toc()
# OP data.table: 4.594 sec elapsed
但是在0.2秒内我们可以获取data.table,转换为数据帧,添加orig_row
行号,按Y分组,按orig_row
反向排序,取X与X的累积最大值之间的差值,取消组合和重新排列原始顺序:
library(dplyr)
tictoc::tic("dplyr")
dt2 <- dt %>%
as_data_frame() %>%
mutate(orig_row = row_number()) %>%
group_by(Y) %>%
arrange(-orig_row) %>%
mutate(max_diff2 = cummax(X) - X) %>%
ungroup() %>%
arrange(orig_row)
tictoc::toc()
# dplyr: 0.166 sec elapsed
all.equal(dt2$max_diff, dt2$max_diff2)
#[1] TRUE
编辑:正如@ david-arenburg在评论中建议的那样,这可以在data.table中以闪亮的方式快速完成,并带有优雅的线条:
dt[.N:1, max_diff2 := cummax(X) - X, by = Y]
在我的计算机上,这比上面的dplyr
解决方案快2-4倍。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.