【问题标题】:Dplyr - Mean for multiple columnsDplyr - 多列的平均值
【发布时间】:2015-04-28 22:42:25
【问题描述】:

我想计算几列的平均值,从而使用dplyr 为平均值创建一个新列,而不需要熔化 + 合并。

> head(growth2)
  CODE_COUNTRY CODE_PLOT IV12_ha_yr IV23_ha_yr IV34_ha_yr IV14_ha_yr IV24_ha_yr IV13_ha_yr
1            1         6       4.10       6.97         NA         NA         NA       4.58
2            1        17       9.88       8.75         NA         NA         NA       8.25
3            1        30         NA         NA         NA         NA         NA         NA
4            1        37      15.43      15.07      11.89      10.00      12.09      14.33
5            1        41      20.21      15.01      14.72      11.31      13.27      17.09
6            1        46      12.64      14.36      13.65       9.07      12.47      12.36
> 

我需要数据集中的一个新列,其中包含所有 IV 列的平均值。 我试过这个:

growth2 %>% 
  group_by(CODE_COUNTRY, CODE_PLOT) %>%
  summarise(IVmean=mean(IV12_ha_yr:IV13_ha_yr, na.rm=TRUE))

并根据使用的示例返回几个错误,例如:

Error in NA_real_:NA_real_ : NA/NaN argument

Error in if (trim > 0 && n) { : missing value where TRUE/FALSE needed

【问题讨论】:

标签: r dplyr


【解决方案1】:

你可以如下使用:

你的数据

data<- structure(list(CODE_COUNTRY = c(1L, 1L, 1L, 1L, 1L, 1L), CODE_PLOT = c(6L, 
17L, 30L, 37L, 41L, 46L), IV12_ha_yr = c(4.1, 9.88, NA, 15.43, 
20.21, 12.64), IV23_ha_yr = c(6.97, 8.75, NA, 15.07, 15.01, 14.36
), IV34_ha_yr = c(NA, NA, NA, 11.89, 14.72, 13.65), IV14_ha_yr = c(NA, 
NA, NA, 10, 11.31, 9.07), IV24_ha_yr = c(NA, NA, NA, 12.09, 13.27, 
12.47), IV13_ha_yr = c(4.58, 8.25, NA, 14.33, 17.09, 12.36)), .Names = c("CODE_COUNTRY", 
"CODE_PLOT", "IV12_ha_yr", "IV23_ha_yr", "IV34_ha_yr", "IV14_ha_yr", 
"IV24_ha_yr", "IV13_ha_yr"), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6"))

mydata <- cbind(data,IVMean=apply(data[,3:8],1,mean, na.rm=TRUE))

你也可以这样做

 mydata <- cbind(data,IVMean=rowMeans(data[3:8], na.rm=TRUE))

【讨论】:

  • 我猜你需要排除 apply 中的前 2 列,因为 OP 只对列 IV12_ha_yr:.... 感兴趣
  • @akrun 嗨,你的意思是这个 mydata
  • 我的意思是 cbind(data,IVMean=apply(data[,3:8],1,mean, na.rm=TRUE)) 根据 OP 的代码,预期的输出是什么有点令人困惑。
  • @akrun 是的,这是肯定的,同时考虑到 NA!
  • 另外,您可以将apply 步骤(或作为替代步骤添加)替换为rowMeans(data[3:8], na.rm=TRUE)
【解决方案2】:

你不需要分组,只需select()然后mutate()

library(dplyr)
mutate(df, IVMean = rowMeans(select(df, starts_with("IV")), na.rm = TRUE))

【讨论】:

  • 这目前不起作用(R 3.2.0 和 dplyr 0.4.1)。我收到以下错误:错误:每个参数必须产生正整数或负整数
  • 它适用于starts_with(),但例如mtcars %&gt;% mutate(IVMean = rowMeans(select(., cyl,mpg), na.rm = TRUE)) 不起作用。如果你把它从变异中取出,它就会起作用。
【解决方案3】:

在 dplyr 中使用 .

library(dplyr)
mutate(df, IVMean = rowMeans(select(., starts_with("IV")), na.rm = TRUE))

【讨论】:

    【解决方案4】:

    我试图评论 Rick Scriven 的回答,但没有经验值。总之,想投稿。他的回答说这样做:

        library(dplyr)
        mutate(df, IVMean = rowMeans(select(df, starts_with("IV")), na.rm = TRUE))
    

    这行得通,但如果所有列都不是以“IV”开头的,这是我的情况,你怎么做?事实证明,该选择不需要逻辑向量,因此您不能使用 AND 或 OR。例如,您不能说“starts_with('X') | starts_with('Y')”。你必须建立一个数字向量。这是它的完成方式。

        mutate(df, IVMean = rowMeans(select(df, c(starts_with("IV"), starts_with("IX"))), na.rm = TRUE))
    

    【讨论】:

    • 您可以使用cbind:例如mutate(df, mean = rowMeans(cbind(my_col_1, my_col_2), na.rm=T)))
    猜你喜欢
    • 2017-09-22
    • 2016-04-04
    • 2013-07-06
    • 2018-07-12
    • 1970-01-01
    • 2021-09-06
    • 2014-08-15
    • 1970-01-01
    相关资源
    最近更新 更多