【问题标题】:How to use tapply from within a for loop如何在 for 循环中使用 tapply
【发布时间】:2015-02-26 21:33:44
【问题描述】:

我有一个 data.frame “df”,它有 200 个观察值和 18 列。 18列是var1,var2等...... 当我使用时:

tapply(df$var1, INDEX=df$varX, FUN=mean, na.rm=T)

其中 varX 是字符串类型的某个变量 (var) 的固定值,对于 varX 的每个值,我得到 var1 的平均值。 我的问题是: 我如何将上述命令放入 for 循环中,以便它迭代相同的命令,从而覆盖所有变量(var1、var2、...等),当然 varX 除外? 我试过这个:

for (k in c(var1, var2, ..., varn)) {
tapply(df$k, INDEX=df$varX, FUN=mean, na.rm=T)
}

但它不起作用。

请注意: 我确信可以使用更有效和更优雅的方法/脚本,但由于我是初学者,而且落后很多,我有时会尝试在阅读完我所拥有的书的相应章节之前继续应用一些想法。这就是为什么我的方法有时看起来很原始的原因。

【问题讨论】:

  • 不要这样做。在data.table 框架内使用aggregate(. ~ varX, df, mean, na.rm = TRUE)summarise_each 来自dplyrlapply(.SD, mean)
  • df$varX 是一个字符变量吗?
  • 您不能将“$”与变量一起使用:stackoverflow.com/questions/3079415/…
  • @vpipkt:是的,df$varX 是一个字符变量

标签: r


【解决方案1】:

您正在寻找的最直接的适应(使用iris作为示例数据框)是:

for(k in iris[-5])   # we loop through the columns in `iris`, except last
  print(tapply(k, INDEX=iris$Species, FUN=mean, na.rm=T))

产生:

setosa versicolor  virginica 
 5.006      5.936      6.588 
setosa versicolor  virginica 
 3.428      2.770      2.974 
setosa versicolor  virginica 
 1.462      4.260      5.552 
setosa versicolor  virginica 
 0.246      1.326      2.026 

使用sapply 代替for 更优雅一些:

sapply(iris[-5], tapply, INDEX=iris$Species, mean, na.rm=T)

产生:

           Sepal.Length Sepal.Width Petal.Length Petal.Width
setosa            5.006       3.428        1.462       0.246
versicolor        5.936       2.770        4.260       1.326
virginica         6.588       2.974        5.552       2.026

但实际上,您想像其他人建议的那样使用 aggregatedplyrdata.table

data.table(iris)[, lapply(.SD, mean, na.rm=TRUE), by=Species]
iris %>% group_by(Species) %>% summarise_each(funs(mean(., na.rm=TRUE)))
aggregate(. ~ Species, iris, mean, na.rm = TRUE) # Courtesy David Arenburg

前两个需要分别加载包data.tabledplyr

【讨论】:

  • 做到了。谢谢你。我肯定会继续阅读有关 R 的文章。
  • 为什么不只是aggregate(. ~ varX, df, mean, na.rm = TRUE)
  • @DavidArenburg 因为我不知道如何使用aggregate? =)
  • 这个也有效:for(k in 4:20) print(tapply(df[[k]], INDEX=df$varX, FUN=mean, na.rm=T)) varX是第三个变量,因此从 k 假定的值中省略。
【解决方案2】:
library(dplyr)
df %>%
na.omit() %>%
group_by(varX) %>%
summarise_each(funs(mean))

【讨论】:

    【解决方案3】:

    您可以使用rowsum(),这是最快的基本 R 聚合函数之一(尽管在这里我们需要将其除以分组变量的计数以获得平均值)。

    按照 BrodieG 的例子,使用 data(iris) 分组 Species,我们可以这样做

    grp <- iris$Species
    rowsum(iris[-5], grp, na.rm = TRUE) / tabulate(grp, nlevels(grp))
    #            Sepal.Length Sepal.Width Petal.Length Petal.Width
    # setosa            5.006       3.428        1.462       0.246
    # versicolor        5.936       2.770        4.260       1.326
    # virginica         6.588       2.974        5.552       2.026
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      • 2019-01-06
      • 2014-11-01
      • 2017-05-24
      • 2018-12-14
      • 2012-10-08
      • 2019-09-18
      相关资源
      最近更新 更多