从多个矩阵计算均值和出现次数

calculate means and occurences from multiple matrices

我有许多矩阵,它们都具有相同类型的元素但长度不同。所有文件中的列都是相同的(我们称它们为“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”的 average/mean 值

   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)

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

非常感谢任何帮助

如果你想坚持基本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

这是一个 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