聚合数据保持字符串

时间:2014-10-31 16:14:10

标签: r aggregate

我有一个与此类似的数据集:

var1 <- c(1, 2, 2, 4, 5)
var2 <- c("Place1", "Place2", "Place3", "Place4", "Place5")
var3 <-c(2, 4, 6, 8, 10)
mydata <- data.frame(var1, var2, var3)

我想通过var1中的因子聚合数据集,得到var3的均值。但是,当我使用aggregate命令执行此操作时:

aggregate(mydata, list(mydata$var1), mean)

它返回var2的NA。理想情况下,它会返回看起来像这样的东西:

    var1 var2              var3
    1    Place1            2
    2    Place2 + Place3   5
    4    Place 4           8
    5    Place 5           10

我无法弄清楚如何使用aggregate命令执行此操作。我还尝试将原始数据集中的var1和var2分配给新数据集,进行聚合,然后将其合并回来,但merge命令再次放入var1的多个值。

4 个答案:

答案 0 :(得分:4)

最好使用&#34; data.table&#34;对于这样的事情:

library(data.table)
as.data.table(mydata)[, list(var2 = paste(var2, collapse = "+"), 
                             var3 = mean(var3)), by = var1]
#    var1          var2 var3
# 1:    1        Place1    2
# 2:    2 Place2+Place3    5
# 3:    4        Place4    8
# 4:    5        Place5   10

或&#34; dplyr&#34;:

library(dplyr)
mydata %>% 
  group_by(var1) %>% 
  summarise(var2 = paste(var2, collapse = "+"), var3 = mean(var3))
# Source: local data frame [4 x 3]
# 
#   var1          var2 var3
# 1    1        Place1    2
# 2    2 Place2+Place3    5
# 3    4        Place4    8
# 4    5        Place5   10

更新

根据您的评论,您可能需要查看以下选项...

以下是一些示例数据:

set.seed(1)
mydata <- data.frame(
  var1 = c(1, 2, 2, 4, 5),
  var2 = c("Place1", "Place2", "Place3", "Place4", "Place5"),
  matrix(sample(5, 20, TRUE), nrow = 5)
)
mydata
#   var1   var2 X1 X2 X3 X4
# 1    1 Place1  2  5  2  3
# 2    2 Place2  2  5  1  4
# 3    2 Place3  3  4  4  5
# 4    4 Place4  5  4  2  2
# 5    5 Place5  2  1  4  4

首先,我们melt,然后我们&#34;聚合&#34;使用&#34; data.table&#34;,然后我们使用dcast.data.table返回宽格式。

dcast.data.table(
  melt(as.data.table(mydata), 
       id.vars = c("var1", "var2"))[, list(
         var2 = paste(var2, collapse = "+"),
         value = mean(value)), by = list(var1, variable)],
  var1 + var2 ~ variable, value.var = "value")
#    var1          var2  X1  X2  X3  X4
# 1:    1        Place1 2.0 5.0 2.0 3.0
# 2:    2 Place2+Place3 2.5 4.5 2.5 4.5
# 3:    4        Place4 5.0 4.0 2.0 2.0
# 4:    5        Place5 2.0 1.0 4.0 4.0

这是使用&#34; dplyr&#34;进行更新的等效方法。和&#34; tidyr&#34;:

library(dplyr)
library(tidyr)
mydata %>%
  gather(var, value, X1:X4) %>%
  group_by(var1, var) %>%
  summarise(var2 = paste(var2, collapse = "+"),
            value = mean(value)) %>%
  ungroup() %>%
  spread(var, value)
# Source: local data frame [4 x 6]
# 
#   var1          var2  X1  X2  X3  X4
# 1    1        Place1 2.0 5.0 2.0 3.0
# 2    2 Place2+Place3 2.5 4.5 2.5 4.5
# 3    4        Place4 5.0 4.0 2.0 2.0
# 4    5        Place5 2.0 1.0 4.0 4.0

答案 1 :(得分:1)

尝试:

> a1 = aggregate(var2~var1, data=mydata, paste, collapse='+')
> a2 = aggregate(var3~var1, data=mydata, mean)
> merge(a1, a2)
  var1          var2 var3
1    1        Place1    2
2    2 Place2+Place3    5
3    4        Place4    8
4    5        Place5   10

答案 2 :(得分:0)

1) aggregate用于在所有列上执行相同操作但在此我们需要var2上的一个操作和{{1上的不同操作(或者其余的)。因此,我们需要使用var3两次。我们可以将第二个aggregate写为aggregate,但我们使用了显示的表单,以便在aggregate(var3 ~ var2, mydata, mean)[-1]之后还有其他变量时,它们也会被平均。 var3是因为两个[-1]表达式都生成aggregate列,我们只需要其中一个。

var1

,并提供:

cbind(aggregate(var2 ~ var1, mydata, toString), 
      aggregate(. ~ var1, mydata[-2], mean)[-1] 
)

2)`您还可以考虑使用多种软件包之一进行此类操作。对于 例如:

  var1           var2 var3 var4
1    1         Place1    2    2
2    2 Place2, Place3    5    5
3    4         Place4    8    8
4    5         Place5   10   10

或者如果要对前两个之后的所有变量进行平均,则分别进行:

library(sqldf)
sqldf("select var1, group_concat(var2) var2, avg(var3) var3 
       from mydata group by var1")

  var1          var2 var3
1    1        Place1    2
2    2 Place2,Place3    5
3    4        Place4    8
4    5        Place5   10

更新添加了第二个解决方案并进行了简化。

答案 3 :(得分:0)

别忘了tapply。

data.frame(var1 = unique(var1),
           var2 = tapply(var2,var1,paste,collapse = ' + '),
           var3 = tapply(var3,var1,mean))

使用mydata data.frame是可选的。

对于评论中请求的同一data.frame中的多个变量:

data.frame(var1 = unique(mydata$var1),
           var2 = tapply(mydata$var2,mydata$var1,paste,collapse = ' + '),
           apply(mydata[,3:5],MARGIN = 2,function(x){
             tapply(x,mydata$var1,mean)
           }))

可以使用[,3:5]但是你需要获得正确的列,例如grep。