繁体   English   中英

如何有效地确定R中data.table中每行中的变量值和后续行值中的相同变量之间的最大差异

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM