【问题标题】:How to select which variables to drop using aggregate function in r [duplicate]如何使用r中的聚合函数选择要删除的变量[重复]
【发布时间】: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


【解决方案1】:

你可以从tidyr 使用complete

library(dplyr)
df %>%
  select(-Donor) %>%
  group_by(Recipient, time) %>%
  tidyr::complete(location = unique(df$location))

#   Recipient  time location  value
#   <chr>     <dbl> <chr>     <dbl>
# 1 r1         2000 in            2
# 2 r1         2000 out           5
# 3 r1         2000 undefined    NA
# 4 r1         2002 in            4
# 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

【讨论】:

  • 这也会聚合值列吗?另外,我是否必须选择掉所有我不想要的列?我问是因为我在更大的数据框上使用它。
  • 我认为aggregate 在这里不合适。我们正在扩展数据以包括每个 Recipienttime 的所有不完整的 location 值。您可以保留不需要的列,这些列将生成 NAvalue 列相同。
  • 感谢您的帮助!在这种情况下,扩展数据对我没有帮助。我需要一个可以聚合数据的函数,同时保留所有location 级别的Recipient
  • @SharifAmlani 您的原始数据有 7 行,您的预期输出有 12 行。那叫什么?你试过答案了吗?
  • 我很抱歉造成混乱。我明白你在说什么。
猜你喜欢
  • 2012-04-15
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
  • 1970-01-01
  • 2021-10-21
相关资源
最近更新 更多