计算数据框中多个列的平均值(和加权平均值)

时间:2016-12-12 18:20:06

标签: r dataframe

摘要

提供了一个数据框,其中我有几个作为变量的列(每个列都是数字但是一个,这是一个因素),行是观察,我想创建一个新列,其中包含所有数字列的平均值+另一个具有所有数字列的加权平均值。

我发现很多方法显然可以解决这个问题(使用dplyrlapplydata.table ...)但是它们都不适用于宽数据帧(我不是我确定我可以把它转换成长格式 - 见下文,请在标记为重复之前耐心等待,因为我没有找到任何问题的答案。)

长版:

我有一个宽格式的数据帧,如下面提供的那样(原始数据帧有超过1700个20个变量的观察值,分为30个邻域),这是计算每个变量值的中值的结果:

df = data.frame(matrix(rnorm(15), nrow = 3))
df$neighbour = c("neighbour1", "neighbour2", "neighbour3")

df
> df
          X1         X2         X3         X4        X5  neighbour
1  1.0384405  0.6116994 -0.2075835  0.3206011 1.3855455 neighbour1
2 -0.5115649 -0.7722500  0.8374265 -1.3697758 0.1690452 neighbour2
3  1.0145282  0.6809156 -0.2918737  0.2912297 1.0689213 neighbour3

我想创建

  • 1)名为mean的列,它是所有数值的平均值(除了neighbour之外的所有列)和
  • 2)wmean列是每列的加权平均值,其中权重由以下向量提供:weight = c(.25, .05, .3, .3, .3)

我的第一次尝试是使用dplyr::mutate来创建这些列,但我没有成功,很可能是因为我做错了(所以如果我没有成功的常规手段,我没有关于如何执行加权平均值的线索):

df = df %>%
  mutate(mean = mean(select(-neighbour)))
Error in mutate_impl(.data, dots) : 
  argumento no válido para un operador unitario
> df = df %>%
+   mutate(mean = mean())
Error in mutate_impl(.data, dots) : 
  el argumento "x" está ausente, sin valor por omisión
> df = df %>%
+   mutate(mean = mean(is.numeric()))
Error in mutate_impl(.data, dots) : 
  0 arguments passed to 'is.numeric' which requires 1
> 

还尝试使用mutate_each,但我假设我的问题是我不知道如何通过正确的列来计算均值(更不用说我对加权均值没有任何线索)。

根据我的阅读,有很多方法可以创建所需的列:

  • This answer by Carlos Cinelli使用sapply + filterdplyrtydr提供示例,但所有这些解决方案均基于他们不创建新列的事实,每个邻居观察的中位数,但每个变量的值的中位数。

  • This answer by @Roland建议使用data.table,但为了能够使用它,我的数据框应该有一个重量的列(而我没有它,我怕我我不知道如何创建这样的列,只要我有超过1700个观察结果)

  • This answer by @Bob使用apply创建了几列的平均值(这与我正在寻找的内容相近!)但仍然不知道如何排除neighbour列,否则它将失败,B)计算加权平均值。

任何人都可以为我带来一些亮点吗?我现在正在努力解决这个问题,我无法看到答案。

编辑:根据@ boshek的answer我试图从宽格式转换为长格式,然后应用summarise_each,但都没有成功:

df = df %>%
  gather(variable, value, -neighbour) %>%
  group_by(neighbour, variable) %>%
  summarise_each(., funs=mean)

4 个答案:

答案 0 :(得分:3)

好的 - 所以你想要意味着ACROSS行吗?

我使用gather中的dplyr,然后将其与原始数据合并:

df.mean <- df %>%
  gather(variable, value, -neighbour) %>%
  group_by(neighbour) %>%
  summarise(mean_value=mean(value), wmean_value=weighted.mean(value))

df.comb <- df %>%
  full_join(.,df.mean, by=c("neighbour"))

有几种方法可以给这只猫上皮,但这只是一种。

这是你想要的吗?

答案 1 :(得分:1)

import pandas as pd
df = pd.DataFrame(range(1, 10))
df.plot(style="o")

答案 2 :(得分:1)

我认为base中的rowMeans()函数可能是您最好的选择。

df$mean <- rowMeans(dplyr::select(df, starts_with("X")))

加权平均值可能更难。我无法找到一种快速而干净的方法来做到这一点,但这是一个有效的选择:

# define a function that calculates a weighted mean
wmean <- function(x, weight){
  stopifnot(length(x) == length(weight))
  if(sum(weight) != 1) {
    message("Rescaling weights to sum to 1")
    weight <- weight/sum(weight)
  }
  wx <- sum(x * weight)
  return(wx)
}
# apply that function row by row to the X columns in df
df$wmean <- apply(X=dplyr::select(df, starts_with("X")), MARGIN=1, FUN=wmean, weight = weight)

答案 3 :(得分:0)

我知道我发布这个有点晚了,但我一直在寻找类似问题的解决方案,并从 rowWeightedMeans 库中找到了 matrixStats,它也支持 na.rm ,你只需要转换成矩阵,它的工作原理如下:

library(matrixStats)
df$wmean <- rowWeightedMeans(as.matrix(df[ , c('X1', 'X2', 'X3', 'X4', 'X5')]), w = weight)

这对我来说非常有效,正如前面提到的,有额外的支持na.rm = TRUE,我需要