【发布时间】:2020-10-16 14:08:32
【问题描述】:
我在 R 中使用 aggregate 函数将数据聚合在一起。我希望它降低一些级别,但保留其他级别。
例如,我正在处理如下所示的数据:
Donor Recipient value location time
1 d1 r1 2 in 2000
2 d2 r2 3 out 2002
3 d3 r3 4 in 2004
4 d4 r1 5 out 2000
5 d5 r2 1 undefined 2002
6 d6 r3 3 out 2004
7 d6 r1 4 in 2002
我想聚合value 列。
具体来说,我想保留location 列中的所有级别,并删除time 列中的所有未使用级别。这样即使对于没有所有三个可能级别的Recipient(即in, out, or undefined),仍然会在聚合中分配所有三个级别。但是,我不希望 Recipient 被分配到 time 列中的每个级别。我只希望他们保持分配的年份。
我希望数据如下所示:
Recipient location time value
r1 in 2000 2
r1 out 2000 5
r1 undefined 2000 NA
r1 in 2002 4
r1 out 2002 NA
r1 undefined 2002 NA
r2 in 2002 NA
r2 out 2002 3
r2 undefined 2002 1
r3 in 2004 4
r3 out 2004 3
r3 undefined 2004 NA
我的尝试
首先,我使用以下公式。它保留分配的time 列,但不会将每个location 因子分配给每个Recipient。
aggregate(value ~ Recipient + location + time, data = df, sum)
Recipient location time value
1 r1 in 2000 2
2 r1 out 2000 5
3 r1 in 2002 4
4 r2 out 2002 3
5 r2 undefined 2002 1
6 r3 in 2004 4
7 r3 out 2004 3
其次,我在aggregate 函数中使用了drop = F 参数。这给了我每个location 级别,这就是我想要的。但它分配了所有time 级别,这是我不想要的。
aggregate(value ~ Recipient + location + time, data = df, sum, drop = F)
Recipient location time value
1 r1 in 2000 2
2 r2 in 2000 NA
3 r3 in 2000 NA
4 r1 out 2000 5
5 r2 out 2000 NA
6 r3 out 2000 NA
7 r1 undefined 2000 NA
8 r2 undefined 2000 NA
9 r3 undefined 2000 NA
10 r1 in 2002 4
11 r2 in 2002 NA
12 r3 in 2002 NA
13 r1 out 2002 NA
14 r2 out 2002 3
15 r3 out 2002 NA
16 r1 undefined 2002 NA
17 r2 undefined 2002 1
18 r3 undefined 2002 NA
19 r1 in 2004 NA
20 r2 in 2004 NA
21 r3 in 2004 4
22 r1 out 2004 NA
23 r2 out 2004 NA
24 r3 out 2004 3
25 r1 undefined 2004 NA
26 r2 undefined 2004 NA
27 r3 undefined 2004 NA
最后,当我删除年份时,它会按我的意愿工作:将每个 location 因子分配给每个 Recipient。但是,我需要保持 time 常量作为聚合的一部分
aggregate(value ~ Recipient + location, data = df, sum, drop = F)
Recipient location value
1 r1 in 6
2 r2 in NA
3 r3 in 4
4 r1 out 5
5 r2 out 3
6 r3 out 3
7 r1 undefined NA
8 r2 undefined 1
9 r3 undefined NA
从这里,我有两个解决方案:1. 单独循环遍历所有年份或 2. 将年份粘贴到 Recipient 并在聚合后提取它。这两个选项都很笨拙。
有没有办法让聚合函数产生我需要的数据结构?
复制数据
Donor <- c("d1","d2","d3","d4","d5","d6","d6")
Recipient <- c("r1", "r2", "r3", "r1", "r2", "r3", "r1")
time <-c(2000, 2002, 2004, 2000, 2002, 2004, 2002)
value <- c(2, 3, 4, 5, 1, 3, 4)
location <- c("in", "out", "in", "out", "undefined", "out", "in")
df <- data.frame(Donor, Recipient, value, location, time)
更新了用于聚合的复制数据
Donor <- c("d1","d2","d3","d4","d5","d6","d6", "d7")
Recipient <- c("r1", "r2", "r3", "r1", "r2", "r3", "r1", "r1")
time <-c(2000, 2002, 2004, 2000, 2002, 2004, 2002, 2002)
value <- c(2, 3, 4, 5, 1, 3, 4, 4)
location <- c("in", "out", "in", "out", "undefined", "out", "in", "in")
df <- data.frame(Donor, Recipient, value, location, time)
Donor Recipient value location time
1 d1 r1 2 in 2000
2 d2 r2 3 out 2002
3 d3 r3 4 in 2004
4 d4 r1 5 out 2000
5 d5 r2 1 undefined 2002
6 d6 r3 3 out 2004
7 d6 r1 4 in 2002
8 d7 r1 4 in 2002
注意:第 7 行和第 8 行需要汇总。
更新数据的预期输出
Recipient time location value
1 r1 2000 in 2
2 r1 2000 out 5
3 r1 2000 undefined NA
4 r1 2002 in 8
5 r1 2002 out NA
6 r1 2002 undefined NA
7 r2 2002 in NA
8 r2 2002 out 3
9 r2 2002 undefined 1
10 r3 2004 in 4
11 r3 2004 out 3
12 r3 2004 undefined NA
【问题讨论】:
-
聚合是在这里使用的错误术语。似乎您希望仅根据数据中出现的值并用 NA 替换未出现的值来显示收件人、位置和时间的所有可能组合的值。
-
这是正确的。但是,我的示例数据并不准确,反映了我的问题。我已更新问题以更准确地反映我正在使用的数据。
-
更新数据的预期输出是什么?
-
更新了问题以反映更新数据的预期输出。非常感谢您的所有帮助
-
然后先聚合,再使用Ronak的方案。
标签: r dataframe aggregate aggregate-functions