2

假设我在 R 中有这个 data.frame:

ages <- data.frame(Indiv = numeric(),
    Age = numeric(),
    W = numeric())
ages[1,] <- c(1,10,2)
ages[2,] <- c(1,15,5)
ages[3,] <- c(2,5,1)
ages[4,] <- c(2,100,2)

ages

  Indiv Age W
1     1  10 2
2     1  15 5
3     2   5 1
4     2 100 2

如果我做:

meanAge <- aggregate(ages$Age,list(ages$Indiv),mean)

我得到每个 Indiv (Group.1) 的平均年龄 (x):

  Group.1    x
1       1 12.5
2       2 52.5

但我想计算年龄的加权算术平均值(体重为 W)。如果我做:

WmeanAge <- aggregate(ages$Age,list(ages$Indiv),weighted.mean,ages$W)

我得到:

Error in weighted.mean.default(X[[1L]], ...) : 
  'x' and 'w' must have the same length

我想我应该有:

  Group.1           x
1       1 13.57142857
2       2 68.33333333

我究竟做错了什么?提前致谢!

4

4 回答 4

11

哦,你打败了我。plyr但无论如何,这是我同时使用and的答案dplyr

ages = data.frame(Indiv = c(1,1,2,2),
              Age = c(10,15,5,100),
              W = c(2,5,1,2))

library(plyr)
ddply(ages, .(Indiv), summarize, 
      mean = mean(Age),
      wmean = weighted.mean(Age, w=W))


library(dplyr)
ages %.% 
  group_by(Indiv) %.% 
  summarise(mean = mean(Age), wmean = weighted.mean(Age, W))
于 2014-05-06T19:18:51.437 回答
2

问题是它aggregate没有拆分w参数——所以 weighted.mean 正在接收 的子集ages$Age,但它没有接收 的等效子集ages$W

试试plyr包!!这很棒。我在我编写的 95% 的脚本中使用它。

library("plyr")

# the plyr package has functions that come in the format of  _ _ ply
# the first blank is the input format, and the second is the output format
# d = data.frame, l = list, a = array, etc.
# thus, with ddply(), you supply a data.frame (ages), and it returns a data.frame (WmeanAge)

# .data is your data set
# .variables is the name of the column (or columns!) to be used to split .data
# .fun is the function you want to apply to each subset of .data

new.weighted.mean <- function(x, ...){
   weighted.mean(x=x[,"Age"], w=x[,"W"], ...)
}

WmeanAge <- ddply(.data=ages, .variables="Indiv", .fun=new.weighted.mean, na.rm=TRUE)
print(WmeanAge)
于 2014-05-06T19:15:04.143 回答
2

如果您想使用基本功能,这是一种可能性

as.vector(by(ages[c("Age","W")],
    list(ages$Indiv),
     function(x) {
         do.call(weighted.mean, unname(x))
     }
))

由于聚合不会对多个列进行子集化,因此我使用更通用by的并将结果简化为向量。

于 2014-05-06T19:28:32.303 回答
1

您的权重值数量与您的组数不匹配,因此聚合无法正确折叠组。这是一个使用 for 循环的非常不雅的解决方案。

ages = data.frame(Indiv=c(1,1,2,2),Age=c(10,15,5,100),W=c(2,5,1,2))

age.Indiv <- vector()
  for(i in unique(ages$Indiv)){
  age.Indiv <- append(age.Indiv, weighted.mean( ages[ages$Indiv == i ,]$Age, 
                      ages[ages$Indiv == i ,]$W))
    } 
  names(age.Indiv) <- unique(ages$Indiv)
    age.Indiv
于 2014-05-06T19:18:44.530 回答