вычислить средние и совпадения из нескольких матриц

У меня есть несколько матриц, все они имеют один и тот же тип элементов, но разную длину. Столбцы во всех файлах одинаковы (назовем их 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")

как вы можете видеть, насколько далеко идут строки, хотя альфа, бета и гамма всегда присутствуют, многие другие не всегда есть

Я хотел бы вычислить 2 вещи: средние значения всех столбцов 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

(где указанные выше числа являются средними значениями всех матриц)

а затем матрицу вхождений, позвольте вызвать ее .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)

и моим следующим шагом было бы сделать одинаковые имена всех матриц. Я пробовал использовать совпадение, но не могу понять, но на данный момент я даже не знаю, лучшая ли это стратегия … И все похожие вопросы связаны со слиянием матриц (это не то, что я хочу делать).

Любая помощь приветствуется

См. также:  SwiftUI - Как остановить ScrollView, получающий касания за другим представлением
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 2
  1. Panos

    Вот примерный подход:

    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
    

    Создано 27 января 2021 года пакетом REPEX (v0.3.0)

    прекрасно бегает! person Panos; 27.01.2021

    +1, Хороший ответ с использованием библиотеки tidyverse! Первую часть можно еще уменьшить с помощью dat <- list(df1, df2, df3) %>% map_dfr(rownames_to_column). person Panos; 27.01.2021

    Спасибо, хорошее замечание! Когда я использовал reduce, мне было сложно писать это. Я изменил это в приведенном выше коде. person Panos; 27.01.2021

  2. Panos

    Если вы хотите придерживаться основы 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
    

    Для матрицы вхождений вы можете использовать функцию table() из R:

    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
    
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: