【问题标题】:calculate means and occurences from multiple matrices从多个矩阵计算平均值和出现次数
【发布时间】:2021-01-27 11:15:26
【问题描述】:

我有许多矩阵,它们都具有相同类型的元素但长度不同。所有文件中的列都是相同的(我们称它们为“A”和“B”),但文件之间的行大多是相同的元素,但并非总是如此。

以下是一些示例数据(以数据框的形式)

df1 <- data.frame(A = 1:3, B = 3:1)
rownames(df1)=c("alpha","beta","gamma")

df2 <- data.frame(A = 1:5,B = 5:1)
rownames(df2)=c("alpha","beta","delta","gamma","zeta")

df3 <- data.frame(A = 1:7, B = 7:1)
rownames(df3)=c("alpha","beta","delta","gamma","zeta","theta","epsilon")

正如您所看到的,即使“alpha”、“beta”和“gamma”总是存在,但许多其他行并不总是存在

我想计算两件事: 所有矩阵中所有 A 和 B 列的平均值,理想情况下,这将通过创建一个 ave.matr 来包含所有行名和列“A”和“B”的平均值/平均值

   A B
   alpha   1 7
   beta    2 6
   delta   3 5
   gamma   4 4
   zeta    5 3
   theta   6 2
   epsilon 7 1

(上面的数字是所有矩阵的平均值)

然后是一个出现矩阵,我们称它为occur.matr,它将计算所有矩阵中每一行的出现次数,它应该看起来像这样

   A B
   alpha   3
   beta    3
   delta   2
   gamma   3
   zeta    2
   theta   1
   epsilon 1

我今天已经开始做这个了,但我不知道该怎么做。

我首先创建了一个列表和一个矩阵,其中包含来自所有矩阵的唯一行名

list=c(rownames(df1),rownames(df2),rownames(df3))
unique=unique(list)
avematr<-matrix(NA,nrow=length(unique),ncol=2)

我的下一步是使所有矩阵的行名相同。我尝试了比赛,但我无法弄清楚,但此刻我什至不知道这是否是最好的策略...... 并且所有类似的问题都与合并矩阵有关(这不是我想要做的)。

非常感谢任何帮助

【问题讨论】:

    标签: r matrix average


    【解决方案1】:

    这是一个 tidyverse 方法:

    library(tidyverse)
    df1 <- data.frame(A = 1:3, B = 3:1)
    rownames(df1)=c("alpha","beta","gamma")
    
    df2 <- data.frame(A = 1:5,B = 5:1)
    rownames(df2)=c("alpha","beta","delta","gamma","zeta")
    
    df3 <- data.frame(A = 1:7, B = 7:1)
    rownames(df3)=c("alpha","beta","delta","gamma","zeta","theta","epsilon")
    
    dat <- list(df1, df2, df3) %>% 
      map_dfr(rownames_to_column)
    
    avg_dat <- dat %>% 
      group_by(id) %>% 
      summarise(A = mean(A),
                B = mean(B)) 
    #> `summarise()` ungrouping output (override with `.groups` argument)
    avg_dat
    #> # A tibble: 7 x 3
    #>   id          A     B
    #>   <chr>   <dbl> <dbl>
    #> 1 alpha    1     5   
    #> 2 beta     2     4   
    #> 3 delta    3     4   
    #> 4 epsilon  7     1   
    #> 5 gamma    3.67  2.33
    #> 6 theta    6     2   
    #> 7 zeta     5     2
    
    occ_dat <- dat %>% count(id)
    occ_dat
    #>        id n
    #> 1   alpha 3
    #> 2    beta 3
    #> 3   delta 2
    #> 4 epsilon 1
    #> 5   gamma 3
    #> 6   theta 1
    #> 7    zeta 2
    

    reprex package (v0.3.0) 于 2021-01-27 创建

    【讨论】:

    • 运行得很漂亮!
    • +1,使用 tidyverse 库的答案很好!使用dat &lt;- list(df1, df2, df3) %&gt;% map_dfr(rownames_to_column) 可以进一步减少第一部分。
    • 谢谢,好点子!写这篇文章时,当我使用reduce 时感觉很复杂。我在上面的代码中改变了它。
    【解决方案2】:

    如果你想坚持基础 R:

    对于平均任务,当您将行名添加为列时,它会使事情变得更容易。这可以防止在组合数据框时对行名进行自动编号。然后,您可以简单地遍历每个唯一的行名并构建平均值。一个快速而肮脏的解决方案可能如下所示:

    df1 <- data.frame(A = 1:3, B = 3:1)
    rownames(df1)=c("alpha","beta","gamma")
    
    df2 <- data.frame(A = 1:5,B = 5:1)
    rownames(df2)=c("alpha","beta","delta","gamma","zeta")
    
    df3 <- data.frame(A = 1:7, B = 7:1)
    rownames(df3)=c("alpha","beta","delta","gamma","zeta","theta","epsilon")
    
    add_row_names_to_df <- function(df) {
        df$rn <- rownames(df)
        return(df)
    }
    
    new_df <- rbind(add_row_names_to_df(df1), 
                    add_row_names_to_df(df2), 
                    add_row_names_to_df(df3))
    
    avg_df <- as.data.frame(matrix(unique(new_df$rn),
                                   nrow = length(unique(new_df$rn)), 
                                   ncol = 3))
    
    for(i in 1:nrow(avg_df)) {
        avg.df[i,] <- c(avg_df[i,1],
                        mean(new_df$A[new_df$rn==avg_df[i,1]]),
                        mean(new_df$B[new_df$rn==avg_df[i,1]]))
    }
    colnames(avg_df) <- c("rowname", "avgA", "avgB")
    avg_df
    

    结果:

      rowname             avgA             avgB
    1   alpha                1                5
    2    beta                2                4
    3   gamma 3.66666666666667 2.33333333333333
    4   delta                3                4
    5    zeta                5                2
    6   theta                6                2
    7 epsilon                7                1
    

    对于出现矩阵,您可以使用 R 中的 table() 函数:

    as.matrix(table(c(rownames(df1),rownames(df2),rownames(df3))))
    

    产量:

            [,1]
    alpha      3
    beta       3
    delta      2
    epsilon    1
    gamma      3
    theta      1
    zeta       2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      • 2011-04-23
      • 1970-01-01
      • 2017-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多