我有两个非常大的 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)]
我做错了什么?谢谢!
我们可以先合并然后总结:
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
步骤:
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