【问题标题】:Merging two data frame lists based on comparing two column values according to one-to-one match rule根据一对一匹配规则比较两个列值合并两个数据框列表
【发布时间】:2014-08-07 02:58:39
【问题描述】:

我有以下两个列表(实际列表会大得多):

 > ratList
     ratGene      ratReplicate    ratAlignment  ratRNAtype
10    Sdhb   Thymus_M_GSM1328752            2        reg
11    Fasn   Thymus_M_GSM1328752            2        reg
12   Dok10   Thymus_M_GSM1328752            2        rev
13   Hspa5   Thymus_M_GSM1328752            2        reg
14   Cmpk1   Thymus_M_GSM1328752            3        reg

> humanList
   humanGene                            humanReplicate humanAlignment humanRNAtype
61    DOCK10 Fetal_Brain_408_AGTCAA_L004_R1_report.txt              6          reg
62     NUDT5 Fetal_Brain_408_AGTCAA_L004_R1_report.txt              5          dup
63      GRM8 Fetal_Brain_408_AGTCAA_L004_R1_report.txt              5          rev
64      PHC3 Fetal_Brain_408_AGTCAA_L004_R1_report.txt              7          reg
65      EI24 Fetal_Brain_408_AGTCAA_L004_R1_report.txt             13          rev

现在我想合并这两个列表并制作表单的数据框/列表df

humanGene humanAlignment humanRNAtype ratGene ratAlignment ratRNAtype
DOCK10        6            reg         Dok10      2          reg

合并过程将在另一个文本文件geneData.txt的帮助下完成:

AAED1,Aaed1
AAGAB,Aagab
AAK1,Aak1
AAMDC,Aamdc
AAMP,Aamp
AANAT,Aanat
AAR2,AAR2

这里每行第一个词对应人类基因,第二个词对应大鼠基因(例如:AAED1是人类基因,对应的大鼠基因是Aaed1)。我需要以某种方式合并ratList和humanList,因此在合并列表的每一行中,我都有文本文件建议的相应的大鼠和人类基因。在humanList 中,如果存在ratList 中不存在的基因的行,我将在制作合并列表时简单地忽略该基因。对于人类列表中不存在的ratList中的基因也是如此。

谁能帮我做这件事?我是 R 新手,在 R 中数据处理对我来说仍然是个谜。

提前致谢。

【问题讨论】:

  • 它们是列表吗?还是它们是数据框?因为它们看起来像数据框

标签: r list generics merge dataframe


【解决方案1】:

你可以试试:

假设geneData.txt 可以读入一个两列data.frame,first column 用于human genes,第二个用于rat genes

geneData <- structure(list(human = c("DOCK10", "NUDT5", "SDHB1", "AAED1", 
"AAGAB"), rat = c("Dok10", "Nud5", "Sdhb", "Aaed1", "Aagab")), .Names = c("human", 
"rat"), class = "data.frame", row.names = c(NA, -5L))



  res <-  merge(merge(geneData, humanlist, by.x="human", by.y="humanGene"), ratlist, by.x="rat", by.y="ratGene")

res[,c(2,4,5,1,7,8)]
 #    human humanAlignment humanRNAtype   rat ratAlignment ratRNAtype
 # 1 DOCK10              6          reg Dok10            2        rev

example 中为geneData:

  • NUDT5humanlist 中找到,但Nud5 不在ratlist 中
  • Sdhbratlist 中找到,但 SDHB1 不在 humanlist 中
  • 两个列表中都没有找到一些基因名称
  • 在这里,两个列表中都只有 Dok10DOCK10

【讨论】:

    【解决方案2】:

    假设它们是数据框而不是列表

    ratList$humanGene <- toupper(ratList$ratGene)
    New.df <- merge(ratList,humanList,by="humanGene")
    

    虽然这组数据中没有任何相同的基因,所以这会将 New.df 作为一个空数据框。 查找 ?merge 以获取其他选项。

    如果它们是每个包含 1 个数据框的列表

    ratList[[1]]$humanGene <- toupper(ratList[[1]]$ratGene)
    New.df <- merge(ratList[[1]],humanList[[1]],by="humanGene")
    

    【讨论】:

      【解决方案3】:

      如果你有两个大的data.frames 要合并,最好使用dplyr 包中的inner_join() 函数,它比merge() 快​​得多。

      首先是数据:

      ratList <- read.table(text="
           ratGene      ratReplicate    ratAlignment  ratRNAtype
      10    Sdhb   Thymus_M_GSM1328752            2        reg
      11    Fasn   Thymus_M_GSM1328752            2        reg
      12   Dok10   Thymus_M_GSM1328752            2        rev
      13   Hspa5   Thymus_M_GSM1328752            2        reg
      14   Cmpk1   Thymus_M_GSM1328752            3        reg
      ", stringsAsFactors=F)
      
      humanList <- read.table(text="
         humanGene                            humanReplicate humanAlignment humanRNAtype
      61    DOCK10 Fetal_Brain_408_AGTCAA_L004_R1_report.txt              6          reg
      62     NUDT5 Fetal_Brain_408_AGTCAA_L004_R1_report.txt              5          dup
      63      GRM8 Fetal_Brain_408_AGTCAA_L004_R1_report.txt              5          rev
      64      PHC3 Fetal_Brain_408_AGTCAA_L004_R1_report.txt              7          reg
      65      EI24 Fetal_Brain_408_AGTCAA_L004_R1_report.txt             13          rev
      
      ", stringsAsFactors=F)
      
      # using the geneData akrun provided
      geneData <- structure(list(
        human = c("DOCK10", "NUDT5", "SDHB1", "AAED1", "AAGAB"), 
        rat = c("Dok10", "Nud5", "Sdhb", "Aaed1", "Aagab")), 
        .Names = c("humanGene", "ratGene"), 
        class = "data.frame", 
        row.names = c(NA, -5L))
      

      在实践中,你可以在geneData中使用,

      geneData <- read.csv("geneData.csv", header=F)
      names(geneData) <- ("humanGene", "ratGene")
      

      以下是一些快速基准测试:

      合并

      library(microbenchmark)
      
      microbenchmark(
        merge(
          merge(geneData, humanList, by="humanGene"),
          ratList, by="ratGene"
        ), unit="us"
      )
      

      输出:

      Unit: microseconds
                                                                                    expr      min       lq   median       uq      max
       merge(merge(geneData, humanList, by = "humanGene"), ratList,      by = "ratGene") 1517.795 1565.213 1584.099 1645.475 6441.493
       neval
         100
      

      dplyr

      microbenchmark(
        inner_join(
          inner_join(humanList, geneData, by="humanGene"),
          ratList, by="ratGene"
        )
      )
      

      输出:

      Unit: microseconds
                                                                                              expr     min      lq   median     uq
       inner_join(inner_join(humanList, geneData, by = "humanGene"),      ratList, by = "ratGene") 251.666 256.388 258.4405 261.93
           max neval
       488.142   100
      

      您可以看到dplyr:::inner_join()merge() 快大约6x~7x,如果您必须重复加入大表,则需要考虑这一点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 2021-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多