我的目标是计算最终数据框,其中包含来自几个不同数据框的均值。给出这样的数据:
A <- c(1,2,3,4,5,6,7,8,9)
B <- c(2,2,2,3,4,5,6,7,8)
C <- c(1,1,1,1,1,1,2,2,1)
D <- c(5,5,5,5,6,6,6,7,7)
E <- c(4,4,3,5,6,7,8,9,7)
DF1 <- data.frame(A,B,C)
DF2 <- data.frame(E,D,C)
DF3 <- data.frame(A,C,E)
DF4 <- data.frame(A,D,E)
我想计算每个数据框中所有三列(每行)的均值。为此,我整理了一个for循环:
All <- data.frame(matrix(ncol = 3, nrow = 9))
for(i in seq(1:ncol(DF1))){
All[,i] <- mean(c(DF1[,i], DF2[,i], DF3[,i], DF4[,i]))
}
X1 X2 X3
1 5.222222 4.277778 3.555556
2 5.222222 4.277778 3.555556
3 5.222222 4.277778 3.555556
4 5.222222 4.277778 3.555556
5 5.222222 4.277778 3.555556
6 5.222222 4.277778 3.555556
7 5.222222 4.277778 3.555556
8 5.222222 4.277778 3.555556
9 5.222222 4.277778 3.555556
但最终结果是我计算了整个列的平均值(而不是每个行的平均值)。
例如,4个数据帧中每个数据帧的第一行和第一列是1,4,1,1。所以我希望最终数据框的第一个col和第一行是1.75(mean(c(1,4,1,1)
)
答案 0 :(得分:4)
我们将数据集放在list
中,使用+
获取相应元素的总和(Reduce
)并将其除以数据集的数量
Reduce(`+`, mget(paste0("DF", 1:4)))/4
# A B C
#1 1.75 3.25 2.5
#2 2.50 3.25 2.5
#3 3.00 3.25 2.0
#4 4.25 3.50 3.0
#5 5.25 4.25 3.5
#6 6.25 4.50 4.0
#7 7.25 5.00 5.0
#8 8.25 5.75 5.5
#9 8.50 5.75 4.0
注意:它应该比任何基于apply
的解决方案更快,输出为原始数据集的data.frame
如果我们想要tidyverse
,那么另一个选项是
library(dplyr)
library(tidyr)
library(purrr)
library(tibble)
mget(paste0("DF", 1:4)) %>%
map(rownames_to_column, "rn") %>%
map(setNames, c("rn", LETTERS[1:3])) %>%
bind_rows() %>%
group_by(rn) %>%
summarise_each(funs(mean))
# A tibble: 9 × 4
# rn A B C
# <chr> <dbl> <dbl> <dbl>
#1 1 1.75 3.25 2.5
#2 2 2.50 3.25 2.5
#3 3 3.00 3.25 2.0
#4 4 4.25 3.50 3.0
#5 5 5.25 4.25 3.5
#6 6 6.25 4.50 4.0
#7 7 7.25 5.00 5.0
#8 8 8.25 5.75 5.5
#9 9 8.50 5.75 4.0
答案 1 :(得分:3)
由于您所描述的实际上是一个数组,您实际上可以使用abind::abind
创建一个数组,这使得操作非常简单:
apply(abind::abind(DF1, DF2, DF3, DF4, along = 3), 1:2, mean)
## A D E
## [1,] 1.75 3.25 2.5
## [2,] 2.50 3.25 2.5
## [3,] 3.00 3.25 2.0
## [4,] 4.25 3.50 3.0
## [5,] 5.25 4.25 3.5
## [6,] 6.25 4.50 4.0
## [7,] 7.25 5.00 5.0
## [8,] 8.25 5.75 5.5
## [9,] 8.50 5.75 4.0
列名无意义,结果是矩阵,而不是data.frame,但即使你将它包装在data.frame
中,它仍然非常快。
答案 2 :(得分:2)
tidyverse
和base
的组合:
#install.packages('tidyverse')
library(tidyverse)
transpose(list(DF1, DF2, DF3, DF4)) %>%
map(function(x)
rowMeans(do.call(rbind.data.frame,
transpose(x)))) %>%
bind_cols()
应该屈服:
# A B C
# <dbl> <dbl> <dbl>
# 1 1.75 3.25 2.5
# 2 2.50 3.25 2.5
# 3 3.00 3.25 2.0
# 4 4.25 3.50 3.0
# 5 5.25 4.25 3.5
# 6 6.25 4.50 4.0
# 7 7.25 5.00 5.0
# 8 8.25 5.75 5.5
# 9 8.50 5.75 4.0