首页 文章

聚合数据保持字符串

提问于
浏览
1

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

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

    对于像这样的事情,你最好使用“data.table”:

    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
    

    或者“dplyr”:

    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 ,然后我们"aggregate"使用"data.table",然后我们使用 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
    

    这是使用“dplyr”和“tidyr”进行更新的等效方法:

    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
    
  • 4

    尝试:

    > 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
    
  • 1

    别忘了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 .

  • 0

    当你想对所有列执行相同的操作时使用 1) aggregate 但是在这里我们想要 var2 上的一个操作和 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] 
    )
    

    赠送:

    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
    

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

    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
    

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

    nms <- tail(names(mydata), -2)
    Names <- toString(sprintf("avg(%s) '%s'", nms, nms))
    fn$sqldf("select var1, group_concat(var2) var2, $Names from mydata group by var1")
    

    Update 添加了第二个解决方案并进行了简化 .

相关问题