【问题标题】:R: Conditional Sum by Row in DataTableR:数据表中的按行条件求和
【发布时间】:2021-09-16 08:49:16
【问题描述】:

我有一个非常大的数据集(数百万行,我需要循环数千次),并且在循环期间我必须做一个似乎需要很长时间的条件求和。有没有办法提高效率?

数据表格式如下:

DT <- data.table('A' = c(1,1,1,2,2,3,3,3,3,4),
                 'B' = c(500,510,540,500,540,500,510,519,540,500),
                 'C' = c(10,20,10,20,10,50,20,50,20,10))
A B C
1 500 10
1 510 20
1 540 10
2 500 20
2 540 10
3 500 50
3 510 20
3 519 50
3 540 20
4 500 10

我需要根据 A == A 和 B >= B & B

A B C D
1 500 10 30
1 510 20 30
1 540 10 10
2 500 20 20
2 540 10 10
3 500 50 120
3 510 20 120
3 519 50 120
3 540 20 20
4 500 10 10

我目前使用的代码:

DT[,D:= sum(DT$C[A == DT$A & ((B >= DT$B) & (B < DT$B + 20))]), by=c('A', 'B')]

这需要很长时间才能实际运行,并且给了我错误的答案。我得到的输出如下所示:

A B C D
1 500 10 10
1 510 20 30
1 540 10 10
2 500 20 20
2 540 10 10
3 500 50 50
3 510 20 70
3 519 50 120
3 540 20 20
4 500 10 10

(即 D 似乎只是累积增加)。

我不太关心累积的东西,更关心速度。最终,我想要得到的是 A 中 C 的最大总和,前提是 B 彼此之间的距离在 20 以内。我真的很感激这方面的任何帮助!提前致谢。

【问题讨论】:

  • 如果除了您的描述之外,您还包括正确的答案,而不仅仅是错误的答案,那将会很有帮助。谢谢!
  • @r2evans 第二张表是预期结果...
  • 但你说这是“给我错误的答案” ...? ... 编辑,我明白了;第二张表是正确的,第三张表是最新的并且不正确。明白了。

标签: r performance sum data.table conditional-statements


【解决方案1】:

如果我理解正确的话,这可以通过非等自加入来解决

DT[, Bp20 := B + 20][
  DT, on = .(A, B >= B, B < Bp20), mult = "last"][
    , .(B, C = i.C, D = sum(i.C)), by = .(A, Bp20)][
      , Bp20 := NULL][]
    A   B  C   D
 1: 1 500 10  30
 2: 1 510 20  30
 3: 1 540 10  10
 4: 2 500 20  20
 5: 2 540 10  10
 6: 3 500 50 120
 7: 3 510 20 120
 8: 3 519 50 120
 9: 3 540 20  20
10: 4 500 10  10

【讨论】:

  • 我一直在纠结这个问题,我很接近但肯定还不够足够。不错。
  • 谢谢,@r2evans。 mult = "last"Bp20 转换为分组变量。
  • 非常感谢您。它不仅让我得到了正确的答案,而且速度更快。谢谢!!
【解决方案2】:
# logic for B
DT[, g := B >= shift(B) & B < shift(B, 1) + 20, by = A]
# creating index column
DT[, gi := !g] 
DT[is.na(gi), gi := T]
DT[, gi := cumsum(gi)]
DT[, D := sum(C), by = gi] # summing by new groups
DT
#     A   B  C     g gi   D
#  1: 1 500 10    NA  1  30
#  2: 1 510 20  TRUE  1  30
#  3: 1 540 10 FALSE  2  10
#  4: 2 500 20    NA  3  20
#  5: 2 540 10 FALSE  4  10
#  6: 3 500 50    NA  5 120
#  7: 3 510 20  TRUE  5 120
#  8: 3 519 50  TRUE  5 120
#  9: 3 540 20 FALSE  6  20
# 10: 4 500 10    NA  7  10

您可能需要调整B 的逻辑,因为从问题中并不清楚所有边缘情况...如果对于一个A 值我们有c(30, 40, 50, 60),所有这些行都在一个组中?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-16
    • 2019-02-24
    • 2014-08-22
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    相关资源
    最近更新 更多