【问题标题】:Colmeans in a dataframe by factor variableColmeans 在数据框中的因子变量
【发布时间】:2015-05-11 13:38:07
【问题描述】:

我正在尝试针对不同因素获取数据框中某些变量的平均值。说我有:

    time    geo var1    var2   var3    var4
1   1990    AT  1       7      13       19
2   1991    AT  2       8      14       20
3   1992    AT  3       9      15       21
4   1990    DE  4       10     16       22
5   1991    DE  5       11     17       23
6   1992    DE  6       12     18       24

我想要:

    time    geo var1    var2   var3    var4   m_var2   m_var3
1   1990    AT  1       7      13       19    8        14
2   1991    AT  2       8      14       20    8        14
3   1992    AT  3       9      15       21    8        14
4   1990    DE  4       10     16       22    11       17
5   1991    DE  5       11     17       23    11       17
6   1992    DE  6       12     18       24    11       17

我用 by() 和 lapply() 尝试了一些东西,但我认为这进入了 ddply 的方向

require(plyr)
Dataset <- data.frame(time=rep(c(1990:1992),2),geo=c(rep("AT",3),rep("DE",3))
      ,var1=as.numeric(c(1:6)),var2=as.numeric(c(7:12)),var3=as.numeric(c(13:18)),
      var4=as.numeric(c(19:24)))

newvars <- c("var2","var3")
newData <- Dataset[,c("geo",newvars)]

目前,我可以在两个错误之间进行选择:

ddply(newData,newData[,"geo"],colMeans) 
#where R apparently thinks AT is the variable?

ddply(newData,"geo",colMeans)
#where R worries about the factor variable not being numeric?

我的 lapply 尝试让我走得很远,但随后给我留下了一个无法返回数据框的列表:

lapply(newvars,function(x){
       by(Dataset[x],Dataset[,"geo"],function(x) 
       rep(colMeans(x,na.rm=T),length(unique(Dataset[,"time"]))))
       })

我认为这甚至必须能够使用合并和过滤器,如下所示: Lapply in a dataframe over different variables using filters ,但我不能把它放在一起。任何帮助将不胜感激!

【问题讨论】:

    标签: r dataframe data.table plyr


    【解决方案1】:

    dplyr的其他方法

    library(dplyr)
    df1 %>% group_by(geo) %>% mutate(m_var2=mean(var2), m_var3=mean(var3))
    

    【讨论】:

      【解决方案2】:

      另一个简单的基本 R 解决方案就是

      transform(df, m_var2 = ave(var2, geo), m_var3 = ave(var3, geo))
      #   time geo var1 var2 var3 var4 m_var2 m_var3
      # 1 1990  AT    1    7   13   19      8     14
      # 2 1991  AT    2    8   14   20      8     14
      # 3 1992  AT    3    9   15   21      8     14
      # 4 1990  DE    4   10   16   22     11     17
      # 5 1991  DE    5   11   17   23     11     17
      # 6 1992  DE    6   12   18   24     11     17
      

      几年后,我认为更简洁的方法是更新实际数据集(而不是创建新数据集)和对列向量进行操作(而不是手动编写它们)

      vars <- paste0("var", 2:3) # Select desired cols
      df[paste0("m_", vars)] <- lapply(df[vars], ave, df[["geo"]]) # Loop and update
      

      【讨论】:

        【解决方案3】:

        一种选择是使用data.table。我们可以将data.frame 转换为data.table (setDT(df1)),通过在.SDcols 中指定列索引来获取选定列('var2' 和'var3')的mean (lapply(.SD, mean)),按“地理”分组。通过将输出 (:=) 分配给新列名称 (paste('m', names(df1)[4:5])) 来创建新列

        library(data.table)
        setDT(df1)[, paste('m', names(df1)[4:5], sep="_") :=lapply(.SD, mean)
                    ,by = geo, .SDcols=4:5]
        #     time geo var1 var2 var3 var4 m_var2 m_var3
        #1: 1990  AT    1    7   13   19      8     14
        #2: 1991  AT    2    8   14   20      8     14
        #3: 1992  AT    3    9   15   21      8     14
        #4: 1990  DE    4   10   16   22     11     17
        #5: 1991  DE    5   11   17   23     11     17
        #6: 1992  DE    6   12   18   24     11     17
        

        注意:这种方法更通用。我们甚至可以为 100 个变量创建 mean 列,而无需对代码进行任何重大更改。 IE。如果我们需要获取 4:100 列的 mean,请更改 .SDcols=4:100paste('m', names(df1)[4:100]

        数据

        df1 <- structure(list(time = c(1990L, 1991L, 1992L, 1990L, 1991L, 1992L
        ), geo = c("AT", "AT", "AT", "DE", "DE", "DE"), var1 = 1:6, var2 = 7:12, 
        var3 = 13:18, var4 = 19:24), .Names = c("time", "geo", "var1", 
        "var2", "var3", "var4"), class = "data.frame", row.names = c("1", 
        "2", "3", "4", "5", "6"))
        

        【讨论】:

        • @DavidArenburg 是吗?好的,我会指定它
        • 这太好了,谢谢!我可以让它运行我自己指定的变量向量,这正是我需要的。
        • @Jakob 我宁愿保留错误的代码,以便其他人理解对错。但是,如果你愿意,你可以删除它
        【解决方案4】:

        baseR:

         cbind(df1,m_var2=ave(df1$var2,df1$geo),m_var3=ave(df1$var3,df1$geo))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-11
          • 2015-04-12
          • 1970-01-01
          • 2018-07-15
          • 2018-04-04
          • 2019-05-08
          相关资源
          最近更新 更多