【问题标题】:Populate table with values from another table based on both rows and columns使用基于行和列的另一个表中的值填充表
【发布时间】:2021-09-30 19:05:24
【问题描述】:

我有一个看起来像这样的空数据框:

df <- data.frame(Hugo_Symbol=c("CDKN2A", "JUN", "IRS2","MTOR",
                          "NRAS"),
                 A183=c(NA, NA, NA, NA, NA),
                 A240=c(NA, NA, NA, NA, NA),
                 A330=c(NA, NA, NA, NA, NA))

我想使用更大的数据框来填充前一个数据框。较大数据框的结构如下:

df2 <- data.frame(Hugo_Symbol=c("CDKN2A", "JUN", "IRS2","MTOR",
                          "NRAS", "TP53", "EGFR"),
                 A183=c(2.3, 3.3, 2.6, 4.7, 1.2, 5.7, 3.4),
                 A240=c(1.3, 2.3, 4.6, 5.7, 2.2, 7.7, 1.4),
                 A330=c(0.3, 2.3, 1.6, 1.7, 4.2, 1.7, 4.4),
                 A335=c(1.3, 0.3, 0.6, 0.7, 0.2, 0.7, 0.4),
                 A345=c(0.3, 4.3, 4.6, 4.7, 4.2, 4.7, 0.4))

我想要的输出应该是这样的:

Hugo_Symbol A183 A240 A330
1      CDKN2A  2.3  1.3  0.3
2         JUN  3.3  2.3  2.3
3        IRS2  2.6  4.6  1.6
4        MTOR  4.7  5.7  1.7
5        NRAS  1.2  2.2  4.2

我尝试使用dplyr 包,特别是semi_join() 函数,但它返回空表给我。

【问题讨论】:

    标签: r dataframe populate


    【解决方案1】:

    我们可以使用连接

    library(data.table)
    nm1 <- names(df)[-1]
    df[nm1] <- lapply(df[nm1], as.numeric)
    setDT(df)[df2, (nm1) := mget(paste0('i.', nm1)), on = .(Hugo_Symbol)]
    

    -输出

    df
       Hugo_Symbol A183 A240 A330
    1:      CDKN2A  2.3  1.3  0.3
    2:         JUN  3.3  2.3  2.3
    3:        IRS2  2.6  4.6  1.6
    4:        MTOR  4.7  5.7  1.7
    5:        NRAS  1.2  2.2  4.2
    

    【讨论】:

      【解决方案2】:

      是否可以只从第一个数据框中删除 NA 列?如果是这样,左连接将产生所需的输出。

      df <- data.frame(
        Hugo_Symbol = c("CDKN2A", "JUN", "IRS2", "MTOR",
                        "NRAS"),
        A183 = c(NA, NA, NA, NA, NA),
        A240 = c(NA, NA, NA, NA, NA),
        A330 = c(NA, NA, NA, NA, NA)
      )
      
      df2 <- data.frame(
        Hugo_Symbol = c("CDKN2A", "JUN", "IRS2", "MTOR",
                        "NRAS", "TP53", "EGFR"),
        A183 = c(2.3, 3.3, 2.6, 4.7, 1.2, 5.7, 3.4),
        A240 = c(1.3, 2.3, 4.6, 5.7, 2.2, 7.7, 1.4),
        A330 = c(0.3, 2.3, 1.6, 1.7, 4.2, 1.7, 4.4),
        A335 = c(1.3, 0.3, 0.6, 0.7, 0.2, 0.7, 0.4),
        A345 = c(0.3, 4.3, 4.6, 4.7, 4.2, 4.7, 0.4)
      )
      
      library(dplyr)
      
      left_join(df["Hugo_Symbol"], df2, by = "Hugo_Symbol")
      
      

      【讨论】:

        【解决方案3】:

        您也可以使用以下解决方案:

        library(dplyr)
        
        df %>%
          left_join(df2, by = "Hugo_Symbol") %>%
          mutate(across(ends_with(".x"), ~ coalesce(.x, get(gsub(".x", ".y", cur_column()))))) %>%
          select(Hugo_Symbol, ends_with(".x")) %>%
          rename_with(~ gsub(".x", "", .), ends_with(".x"))
        
          Hugo_Symbol A183 A240 A330
        1      CDKN2A  2.3  1.3  0.3
        2         JUN  3.3  2.3  2.3
        3        IRS2  2.6  4.6  1.6
        4        MTOR  4.7  5.7  1.7
        5        NRAS  1.2  2.2  4.2
        

        【讨论】:

          【解决方案4】:

          另一种方法-

          • left_joinhugo_symbol
          • 然后在仅以后缀.yhugo_symbol 结尾的那些列上使用transmute across
          • 按原样保留值。因此~.
          • 使用.names 参数从名称中删除.y。使用正则表达式[.]y,这样它就不会被解释为通配符和y。
          library(dplyr)
          
          df %>% left_join(df2, by = 'Hugo_Symbol') %>%
            transmute(across(Hugo_Symbol | ends_with('.y'), ~., .names = '{gsub("[.]y", "", .col )}'))
          
          #>   Hugo_Symbol A183 A240 A330
          #> 1      CDKN2A  2.3  1.3  0.3
          #> 2         JUN  3.3  2.3  2.3
          #> 3        IRS2  2.6  4.6  1.6
          #> 4        MTOR  4.7  5.7  1.7
          #> 5        NRAS  1.2  2.2  4.2
          

          reprex package (v2.0.0) 于 2021 年 7 月 24 日创建

          【讨论】:

          • 这很聪明!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-21
          • 2019-06-14
          • 2022-08-18
          • 1970-01-01
          • 2015-04-17
          • 1970-01-01
          相关资源
          最近更新 更多