从不同的数据框计算均值

时间:2017-01-14 17:35:01

标签: r dataframe mean

我的目标是计算最终数据框,其中包含来自几个不同数据框的均值。给出这样的数据:

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)

3 个答案:

答案 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)

tidyversebase的组合:

#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