【问题标题】:R: aggregate based on factor or numericR:基于因子或数字的聚合
【发布时间】:2014-10-06 16:01:38
【问题描述】:

我正在尝试聚合一些既是数值变量又是因子变量的数据。如果变量是数字,我想要平均值。如果这是一个因素,我想要最常出现的值。我编写了以下函数,但没有得到我想要的输出:

meanOrMostFreq <- function(x){
    if(class(x) == 'factor'){
    tbl <- as.data.frame(table(x))
    tbl$Var1 <- as.character(tbl$Var1)
    return(tbl[tbl$Freq == max(tbl$Freq),'Var1'][1])
    }
    if(class(x) == 'numeric'){
    meanX <- mean(x, na.rm = TRUE)
    return(meanX)
    }
}

这是我的使用方法:

df1 <- iris[1:148,]
df1$letter1 <- as.factor(rep(letters[1:4], 37))

momf <- aggregate(.~ Species, df1, FUN = function(x) meanOrMostFreq(x))

结果:

> momf
     Species Sepal.Length Sepal.Width Petal.Length Petal.Width letter1
1     setosa     5.006000    3.428000     1.462000       0.246    2.46
2 versicolor     5.936000    2.770000     4.260000       1.326    2.54
3  virginica     6.610417    2.964583     5.564583       2.025    2.50

我希望在最后一列中得到一个实际的字母,而不是一个数字。关于我做错了什么有什么建议吗?

【问题讨论】:

  • 很确定aggregate 不会使用非数字。您可能只需要一个不同的工具。
  • 您可以通过data.table轻松实现您想要的。无论如何,您的meanOrMostFreq 中有一些错误。首先,它应该是as.data.frame(table(x))。然后生成的列将被命名为x 而不是Var。您在aggregate 调用中看不到这些错误,因为它强制转换为数字。试试meanOrMostFreq(df1$letters)
  • @nicola:你在 table(x) 和 var vs Var1 上是正确的。我进行了更改,但仍然遇到相同的错误。

标签: r aggregate


【解决方案1】:

这是一种使用data.table的方法

library(data.table)
setDT(df1)[ ,lapply(.SD, function(x) if(is.numeric(x)) mean(x, na.rm=TRUE) else
          names(which.max(table(x)))) , by=Species]

#         Species Sepal.Length Sepal.Width Petal.Length Petal.Width letter1
#1:     setosa     5.006000    3.428000     1.462000       0.246       a
#2: versicolor     5.936000    2.770000     4.260000       1.326       c
#3:  virginica     6.610417    2.964583     5.564583       2.025       a

【讨论】:

    【解决方案2】:

    通过公式界面到aggregate 显然丢失了它的一个因素的元数据;这对我有用:

    > meanOrMostFreq
    function(x){
        if(class(x) == 'factor'){
        return(  names(which.max(table(x))) )
        }
        if(class(x) == 'numeric'){
        meanX <- mean(x, na.rm = TRUE)
        return(meanX)
        }
    }
    > aggregate(df1[-5], df1[5], meanOrMostFreq)
         Species Sepal.Length Sepal.Width Petal.Length Petal.Width letter1
    1     setosa     5.006000    3.428000     1.462000       0.246       a
    2 versicolor     5.936000    2.770000     4.260000       1.326       c
    3  virginica     6.610417    2.964583     5.564583       2.025       a
    

    由于aggregate.formulaaggregate.data.frame 的行为不同,这对我来说就像一个错误。

    【讨论】:

      【解决方案3】:

      使用plyr 包的替代方案:

      ddply(df1, .(Species), function(df) {
          sapply(df, meanOrMostFreq)
      })
      

      []的

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-24
        • 2019-12-08
        • 2015-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多