按多列聚合并从长到大重新整形

时间:2017-12-22 20:54:42

标签: r dplyr aggregate mean group-summaries

在SO上有一些类似于这个主题的问题但不完全像我的用例。我有一个数据集,其中的列布局如下所示

     Id        Description          Value
     10        Cat                  19
     10        Cat                  20
     10        Cat                  5
     10        Cat                  13
     11        Cat                  17
     11        Cat                  23
     11        Cat                  7
     11        Cat                  14  
     10        Dog                  19
     10        Dog                  20
     10        Dog                  5
     10        Dog                  13
     11        Dog                  17
     11        Dog                  23
     11        Dog                  7
     11        Dog                  14    

我要做的是通过Id,Description来捕获Value列的平均值。最终的数据集看起来像这样。

     Id       Cat         Dog 
     10       14.25       28.5
     11       15.25       15.25

我可以用非常粗暴的方式做到这一点,不像这样高效率

tempdf1 <- df %>%
  filter(str_detect(Description, "Cat")) %>%
   group_by(Id, Description) %>%
  summarize(Mean_Value = mean(Value) , na.rm = TRUE))

这不太方便。任何关于如何更有效地完成预期结果的建议都非常感激。

4 个答案:

答案 0 :(得分:2)

我会使用tapply执行此操作:

with( dat, tapply(Value, list(Id,Description), mean))
     Cat   Dog
10 14.25 14.25
11 15.25 15.25

是否返回矩阵对象,因此请勿尝试使用“$”进行访问。

答案 1 :(得分:1)

您可以使用public enum PlanOptions { [Description("Adult (USD 15 each) 18 – 65 years old")] Adult = 1, [Description("Child (USD 60 each ) 0 – 17 years old")] Child = 2, [Description("Family (USD 120 for the whole family) *Maximum of 2 parents and 3 children per plan.")] Family = 3, }; 汇总(计算平均值)每个群组,并使用data.table获取所需的表格格式:

dcast()

答案 2 :(得分:1)

使用dcast

中的acast甚至reshape2()
dcast(dat,Id~Description,mean)
   Id   Cat   Dog
 1 10 14.25 14.25
 2 11 15.25 15.25

Base R可能会更长时间:

 reshape(aggregate(.~Id+Description,dat,mean),direction = "wide",v.names  = "Value",idvar = "Id",timevar = "Description")
  Id Value.Cat Value.Dog
1 10     14.25     14.25
2 11     15.25     15.25

答案 3 :(得分:1)

您可以使用summarise执行dplyr,使用tidyr::spread从长到大转换:

library(dplyr)
library(tidyr)

df %>%
    group_by(Id, Description) %>%
    summarise(Mean = mean(Value)) %>% 
    spread(Description, Mean)

     Id   Cat   Dog
* <int> <dbl> <dbl>
1    10 14.25 14.25
2    11 15.25 15.25