【问题标题】:Mean of 3 dataframes with same dimensions3个具有相同维度的数据框的平均值
【发布时间】:2020-04-24 14:09:28
【问题描述】:

我有 3 个具有相似尺寸的数据框,结构如下:

> str(Results_first_experiment)

Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   30 obs. of  8 variables:
 $ Strain: chr  "1" "2" "3" "4" ...
 $ 0.5   : num  3452 4126 2200 3125 1392 ...
 $ 1     : num  11918 14445 7899 11735 5813 ...
 $ 2     : num  19848 20872 16089 19759 13746 ...
 $ 3     : num  20188 19937 20509 21012 19792 ...
 $ 4     : num  16586 17074 15426 14748 15470 ...
 $ 5     : num  16850 17288 17801 14051 17305 ...
 $ 6     : num  12816 14682 16325 15948 16069 ...  

> head (Results_first_experiment)
# A tibble: 6 x 8
  Strain `0.5`    `1`    `2`    `3`    `4`    `5`    `6`
  <chr>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
1 1      3452. 11918. 19848. 20188. 16586. 16850. 12816 
2 2      4126  14445. 20872. 19937. 17074. 17288  14682.
3 3      2200.  7899. 16089. 20509  15426. 17801  16325.
4 4      3125. 11735. 19758. 21012. 14748  14051. 15948.
5 5      1392.  5813. 13746  19792. 15470. 17305. 16069.
6 6      1501   5769  12730  18339. 17369  18645. 18463.

我想检索每个位置的 3 个数据帧的平均值。我试着看看How to get mean, median, and other statistics over entire matrix, array or dataframe?。但是我无法获得每个位置 3 个数据帧的平均值

任何帮助将不胜感激。

【问题讨论】:

标签: r dataframe mean


【解决方案1】:

由于第一列是字符,我假设您想在所有数据框中忽略该列。你可以这样做

(df1[-1] + df2[-1] + df3[-1])/3

如果有多个这样的数据框将它们放在一个列表中并使用Reduce

list_df <- list(df1[-1], df2[-1], df3[-1])
Reduce("+", list_df) / length(list_df)

或者使用管道

library(magrittr)
library(purrr)

list_df %>% reduce(`+`) %>% divide_by(length(list_df))

【讨论】:

    【解决方案2】:

    这样的东西应该可以扩展以进行更多操作

    library(tidyverse)
    
    list_random_dfs <- list(mtcars,iris,women)
    
    pipe_to_do <- . %>% 
      select_if(is.numeric) %>% 
      summarise_all(list(means = ~mean(.,na.rm = TRUE)))
    
    mtcars %>% pipe_to_do()
    #>   mpg_means cyl_means disp_means hp_means drat_means wt_means qsec_means
    #> 1  20.09062    6.1875   230.7219 146.6875   3.596563  3.21725   17.84875
    #>   vs_means am_means gear_means carb_means
    #> 1   0.4375  0.40625     3.6875     2.8125
    
    list_random_dfs %>% 
      map(pipe_to_do)
    #> [[1]]
    #>   mpg_means cyl_means disp_means hp_means drat_means wt_means qsec_means
    #> 1  20.09062    6.1875   230.7219 146.6875   3.596563  3.21725   17.84875
    #>   vs_means am_means gear_means carb_means
    #> 1   0.4375  0.40625     3.6875     2.8125
    #> 
    #> [[2]]
    #>   Sepal.Length_means Sepal.Width_means Petal.Length_means Petal.Width_means
    #> 1           5.843333          3.057333              3.758          1.199333
    #> 
    #> [[3]]
    #>   height_means weight_means
    #> 1           65     136.7333
    

    reprex package (v0.3.0) 于 2020-01-07 创建

    【讨论】:

      【解决方案3】:

      当数据都是数值时,更常见的是使用矩阵而不是数据框,可以将其放入数组(多维矩阵)中。您可以将字符列"Strain" 中的信息转换为行名并将其删除。因此,您计划进行的计算可以最轻松地完成。

      apply(A, 1:2, mean)  # mean of superimposed cells 
      #   X1 X2 X3 X4
      # 1  2  5  8 11
      # 2  3  6  9 12
      # 3  4  7 10 13
      

      为了得到数组,我将使用这个小的 data.frame-to-matrix 转换器辅助函数,

      d2m <- function(d, excl=1) `rownames<-`(as.matrix(d[-excl]), d[, 1])
      

      其中excl= 不包括列(这里只是1)。

      d2m 可以使用sapplylappy 的近亲)和选项simplify="array" 同时应用于所有数据帧。要列出您的数据框,您可以使用list(df1, df2, ...) 或使用mget() 并像我一样按模式列出。

      A <- sapply(mget(ls(pattern="^Results")), d2m, simplify="array")
      

      数组长这样,

      A
      , , Results_first_experiment
      
        X1 X2 X3 X4
      1  1  4  7 10
      2  2  5  8 11
      3  3  6  9 12
      
      , , Results_second_experiment
      
        X1 X2 X3 X4
      1  2  5  8 11
      2  3  6  9 12
      3  4  7 10 13
      
      , , Results_third_experiment
      
        X1 X2 X3 X4
      1  3  6  9 12
      2  4  7 10 13
      3  5  8 11 14
      

      可以使用A[,,1]A[,,2]、...单独访问每个矩阵。

      现在所有的计算都可以轻松完成了,试试吧:

      apply(A, 1:2, mean)  # mean superimposed cells
      apply(A, c(1, 3), mean)  # row means each matrix
      apply(A, c(2, 3), mean)  # column means each matrix
      apply(A, 1, mean)  # mean superimposed rows
      apply(A, 2, mean)  # mean superimposed columns
      apply(A, 3, mean)  # entire mean of each matrix
      mean(A)  # mean of entire array
      

      如果您已经使用矩阵,它们可能会像这样排列:

      A <- array(c(m1, m2, m3), dim=c(3, 4, 3))  # Note: dim=c(nrow, ncol, nmat)
      

      数据:

      Results_first_experiment <- structure(list(St = c("1", "2", "3"), X1 = 1:3, X2 = 4:6, X3 = 7:9, 
          X4 = 10:12), class = "data.frame", row.names = c(NA, -3L))
      
      Results_second_experiment <- structure(list(St = c("1", "2", "3"), X1 = c(2, 3, 4), X2 = c(5, 
      6, 7), X3 = c(8, 9, 10), X4 = c(11, 12, 13)), class = "data.frame", row.names = c(NA, 
      -3L))
      
      Results_third_experiment <- structure(list(St = c("1", "2", "3"), X1 = c(3, 4, 5), X2 = c(6, 
      7, 8), X3 = c(9, 10, 11), X4 = c(12, 13, 14)), class = "data.frame", row.names = c(NA, 
      -3L))
      

      【讨论】:

        【解决方案4】:

        首先,在数据表或矩阵中,我建议您不要只用数字命名列。如果您在职位上工作,例如可以命名为“p.1”、“pos.1”等。

        当您为对象(您的位置)重复 data.frames 时,您可以使用 tidyverse 轻松使用。这是一个简单的示例,您可以将其转置到您的数据中:

        size <- 5
        vec.list <- vector("list", size)
        position <- paste0("position.", 1:size)
        
        for(i in 1:size){
          a <- runif(5, 0, 1)
          b <- rnorm(5, 2, 4)
          c <- rnorm(5, 0.5, 1)
          vec.list[[i]] <- data.frame(position, a, b, c)
        }
        vec.list
        
        # unlist to get a data.frame and sort according to position
        df.pos <- do.call(rbind.data.frame, vec.list) %>% arrange(position)
        
        # use tidyr::nest() to nest your data by position
        pos.nested <- df.pos %>% group_by(position) %>% nest()
        
        # Then use purrr::map() functions to work on nested data
        map(.x = pos.nested$data, .f = ~mean(.x$a, na.rm = T))
        map(.x = pos.nested$data, .f = ~sd(.x$c, na.rm = T))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-11-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多