将两列的每个组合配对并计算 data.table 中第三列的总和

问题描述 投票:0回答:2

我有两个非常大的 df:df 1 和 df2。 Df 1 包含“from”、“to”和“count”列。 “from”和“to”中的值代表通勤点并且可以出现多次:

来自1 到1
10020 10020 20
10020 10020 10
10020 22001 不适用
30030 20020 2
45001 32001 100
45001 32001 不适用
45001 45001 1
90080 45002 不适用

在 df 2 中,我想为“from”和“to”创建每种可能的组合。然后,我想填写一个新列“count_total”,即每对通勤者的总和。如果组合没有出现在 df 1 中,我想填写 0。对于 NA,我想填写 0。我想要的输出:

来自2 到2 总数
10020 10020 30
10020 22001 0
10020 20020 0
10020 32001 0
10020 45001 0
10020 45002 0
30030 10020 0
30030 22001 0
30030 20020 2

...

我尝试了以下方法,但是,它没有正确总结“count_total”的值。

    df2 <- CJ(from2 = unique(df1$from1), 
                to2 = unique(df1$to1))


    df2[, count_total := sum(df1$count[
             df1$from1 == from2 &
               df1$to1 == to2
                ]), by = .(from2, to2)]

我做错了什么?谢谢!

merge data.table unique key-value cross-join
2个回答
0
投票

我们可以先合并然后总结:

library(data.table)
setDT(df1)
CJ(from2 = unique(df1$from1), to2 = unique(df1$to1)
  )[df1, count2 := i.count, on = .(from2==from1, to2==to1)
  ][, .(count2 = sum(c(0, count2), na.rm = TRUE)), by = .(from2, to2)]
#     from2   to2 count2
#     <int> <int>  <num>
#  1: 10020 10020     10
#  2: 10020 20020      0
#  3: 10020 22001      0
#  4: 10020 32001      0
#  5: 10020 45001      0
#  6: 10020 45002      0
#  7: 30030 10020      0
#  8: 30030 20020      2
#  9: 30030 22001      0
# 10: 30030 32001      0
# ---                   
# 15: 45001 22001      0
# 16: 45001 32001      0
# 17: 45001 45001      1
# 18: 45001 45002      0
# 19: 90080 10020      0
# 20: 90080 20020      0
# 21: 90080 22001      0
# 22: 90080 32001      0
# 23: 90080 45001      0
# 24: 90080 45002      0

0
投票

步骤:

  1. 加载需要的包
  2. 使用 lazy_dt() 处理 dt,因此我们可以在其上使用 函数
  3. Summarise,合并具有相同 from1 和 to1 的行
  4. 完成数据,为 from1 和 to1 的每个组合创建行,默认值为 0
  5. 由于它现在很懒,我们调用 as.data.table() 让它实际完成工作
pacman::p_load(data.table, dtplyr)

dt <- dt |> lazy_dt()

dt |> 
  summarise(count = sum(count, na.rm = TRUE), .by = c(from1, to1)) |>
  complete(from1, to1, fill = list(count = 0)) |> 
  as.data.table()

输出:

    from1   to1 count
 1: 10020 10020    30
 2: 10020 20020     0
 3: 10020 22001     0
 4: 10020 32001     0
 5: 10020 45001     0
 6: 10020 45002     0
 7: 30030 10020     0
 8: 30030 20020     2
 9: 30030 22001     0
10: 30030 32001     0
11: 30030 45001     0
12: 30030 45002     0
13: 45001 10020     0
14: 45001 20020     0
15: 45001 22001     0
16: 45001 32001   100
17: 45001 45001     1
18: 45001 45002     0
19: 90080 10020     0
20: 90080 20020     0
21: 90080 22001     0
22: 90080 32001     0
23: 90080 45001     0
24: 90080 45002     0
    from1   to1 count
© www.soinside.com 2019 - 2024. All rights reserved.