我希望按几个(实际上约60个)列中的每一列获得加权平均值。这个问题非常类似于:repeatedly applying ave for computing group means in a data frame刚问过。
到目前为止,我已经提出了两种获得加权方法的方法:
sapply
语句sapply
for-loop
声明
醇>
但是,我觉得必须有一种方法可以在apply
语句中插入sapply
语句,反之亦然,从而消除for-loop
。我尝试了许多排列而没有成功。我还查看了sweep
函数。
这是我到目前为止的代码。
df <- read.table(text= "
region state county weights y1980 y1990 y2000
1 1 1 10 100 200 50
1 1 2 5 50 100 200
1 1 3 120 1000 500 250
1 1 4 2 25 100 400
1 1 4 15 125 150 200
2 2 1 1 10 50 150
2 2 2 10 10 10 200
2 2 2 40 40 100 30
2 2 3 20 100 100 10
", header=TRUE, na.strings=NA)
# add a group variable to the data set
group <- paste(df$region, '_', df$state, '_', df$county, sep = "")
df <- data.frame(group, df)
# obtain weighted averages for y1980, y1990 and y2000
# one column at a time using one sapply per column
sapply(split(df, df$group), function(x) weighted.mean(x$y1980, w = x$weights))
sapply(split(df, df$group), function(x) weighted.mean(x$y1990, w = x$weights))
sapply(split(df, df$group), function(x) weighted.mean(x$y2000, w = x$weights))
# obtain weighted average for y1980, y1990 and y2000
# one column at a time using a for-loop
y <- matrix(NA, nrow=7, ncol=3)
group.b <- df[!duplicated(df$group), 1]
for(i in 6:8) {
y[,(i-5)] <- sapply(split(df[,c(1:5,i)], df$group), function(x) weighted.mean(x[,6], w = x$weights))
}
# add weighted averages to the original data set
y2 <- data.frame(group.b, y)
colnames(y2) <- c('group','ave1980','ave1990','ave2000')
y2
y3 <- merge(df, y2, by=c('group'), all = TRUE)
y3
最近对我的所有问题表示歉心,感谢您的任何建议。
已编辑以显示y3
group region state county weights y1980 y1990 y2000 ave1980 ave1990 ave2000
1 1_1_1 1 1 1 10 100 200 50 100.0000 200.0000 50.0000
2 1_1_2 1 1 2 5 50 100 200 50.0000 100.0000 200.0000
3 1_1_3 1 1 3 120 1000 500 250 1000.0000 500.0000 250.0000
4 1_1_4 1 1 4 2 25 100 400 113.2353 144.1176 223.5294
5 1_1_4 1 1 4 15 125 150 200 113.2353 144.1176 223.5294
6 2_2_1 2 2 1 1 10 50 150 10.0000 50.0000 150.0000
7 2_2_2 2 2 2 10 10 10 200 34.0000 82.0000 64.0000
8 2_2_2 2 2 2 40 40 100 30 34.0000 82.0000 64.0000
9 2_2_3 2 2 3 20 100 100 10 100.0000 100.0000 10.0000
答案 0 :(得分:5)
我建议使用package data.table:
library(data.table)
dt <- as.data.table(df)
dt2 <- dt[,lapply(.SD,weighted.mean,w=weights),by=list(region,state,county)]
print(dt2)
region state county weights y1980 y1990 y2000
1: 1 1 1 10.00000 100.0000 200.0000 50.0000
2: 1 1 2 5.00000 50.0000 100.0000 200.0000
3: 1 1 3 120.00000 1000.0000 500.0000 250.0000
4: 1 1 4 13.47059 113.2353 144.1176 223.5294
5: 2 2 1 1.00000 10.0000 50.0000 150.0000
6: 2 2 2 34.00000 34.0000 82.0000 64.0000
7: 2 2 3 20.00000 100.0000 100.0000 10.0000
如果您希望以后可以merge
使用原始data.table:
merge(dt,dt2,by=c("region","state","county"))
region state county weights.x y1980.x y1990.x y2000.x weights.y y1980.y y1990.y y2000.y
1: 1 1 1 10 100 200 50 10.00000 100.0000 200.0000 50.0000
2: 1 1 2 5 50 100 200 5.00000 50.0000 100.0000 200.0000
3: 1 1 3 120 1000 500 250 120.00000 1000.0000 500.0000 250.0000
4: 1 1 4 2 25 100 400 13.47059 113.2353 144.1176 223.5294
5: 1 1 4 15 125 150 200 13.47059 113.2353 144.1176 223.5294
6: 2 2 1 1 10 50 150 1.00000 10.0000 50.0000 150.0000
7: 2 2 2 10 10 10 200 34.00000 34.0000 82.0000 64.0000
8: 2 2 2 40 40 100 30 34.00000 34.0000 82.0000 64.0000
9: 2 2 3 20 100 100 10 20.00000 100.0000 100.0000 10.0000
答案 1 :(得分:1)
我想出了如何在sapply
内嵌套apply
以按组和列获取加权平均值,而不使用显式for-loop
。下面我提供数据集,apply
语句以及apply
语句如何工作的解释。
以下是原始帖子中的数据集:
df <- read.table(text= "
region state county weights y1980 y1990 y2000
1 1 1 10 100 200 50
1 1 2 5 50 100 200
1 1 3 120 1000 500 250
1 1 4 2 25 100 400
1 1 4 15 125 150 200
2 2 1 1 10 50 150
2 2 2 10 10 10 200
2 2 2 40 40 100 30
2 2 3 20 100 100 10
", header=TRUE, na.strings=NA)
# add a group variable to the data set
group <- paste(df$region, '_', df$state, '_', df$county, sep = "")
df <- data.frame(group, df)
以下是apply
/ sapply
代码,用于获取所需的加权平均值。
apply(df[,6:ncol(df)], 2, function(x) {sapply(split(data.frame(df[,1:5], x), df$group), function(y) weighted.mean(y[,6], w = y$weights))})
以下是对apply
/ sapply
声明的解释:
请注意,apply
语句一次选择一个df
的第6列到第8列。
对于这三列中的每一列,我创建了一个新的数据框,将该单独的列与df
的前五列组合在一起。
然后我通过分组变量df$group
将每个新的6列数据帧拆分成块。
一旦将六列的数据框拆分为各个块,我计算每个块的最后一列(第6列)的加权平均值。
结果如下:
y1980 y1990 y2000
1_1_1 100.0000 200.0000 50.0000
1_1_2 50.0000 100.0000 200.0000
1_1_3 1000.0000 500.0000 250.0000
1_1_4 113.2353 144.1176 223.5294
2_2_1 10.0000 50.0000 150.0000
2_2_2 34.0000 82.0000 64.0000
2_2_3 100.0000 100.0000 10.0000
使用包data.table
很不错,但在我更熟悉它的语法以及该语法与data.frame
的语法有何不同之处之前,我认为知道如何使用{{1}会很好}和apply
做同样的事情。现在我可以使用这两种方法,加上原帖中的方法,检查一个方法与其他方法,并了解所有这些方法。