【问题标题】:Creating subset of rows depending on multiple values in one column根据一列中的多个值创建行子集
【发布时间】:2014-07-29 19:48:24
【问题描述】:

我有一个这样的数据文件,其中前两列是人类和大鼠中对应的基因名称(基本上相同的名称,不同的大小写)

Human   Rat     RNAtype    Exp  Organ
BBS1    Bbs1    reg         7   Lung
ASAP2   Asap2   reg         5   Heart
ASAP2   Asap2   CANONICAL   5   Heart
ASAP2   Asap2   reg         6   Heart
ASAP2   Asap2   reg         8   Lung
ASAP3   Asap3   SCRAMBLED   5   Heart
ASAP3   Asap3   scram       8   Heart
ASAP3   Asap3   CANONICAL   5   Heart
ASAP3   Asap3   reg         5   Heart

现在我想通过以下方式制作它的子集。如果一个基因同时存在于肺和心脏中,那么我将把它包含在我的子集中。例如,第一行中的基因 BBS1 仅存在于肺中,而不存在于心脏中,因此它不会出现在子集中。但 ASAP2 存在于心脏和肺中。所以,它会在子集中。 ASAP3 不会在子集中,因为它不存在于肺中。

现在实际的数据文件相当大。而且基因很多,第一列/第二列中基因名称的顺序不像这里那样排序,可以是ASAP2,ASAP3,ASAP3,BBS1,ASAP2,ASAP2。

【问题讨论】:

    标签: r subset


    【解决方案1】:

    这是另一种策略:

    > u <- with(df, by(Human, Organ, unique))
    > df[df$Human %in% intersect(u[[1]], u[[2]]), ]
      Human   Rat   RNAtype Exp Organ
    2 ASAP2 Asap2       reg   5 Heart
    3 ASAP2 Asap2 CANONICAL   5 Heart
    4 ASAP2 Asap2       reg   6 Heart
    5 ASAP2 Asap2       reg   8  Lung
    

    【讨论】:

      【解决方案2】:

      试试这个:

      # read in sample data
      df<-read.table(text="
      Human   Rat     RNAtype    Exp  Organ
      BBS1    Bbs1    reg         7   Lung
      ASAP2   Asap2   reg         5   Heart
      ASAP2   Asap2   CANONICAL   5   Heart
      ASAP2   Asap2   reg         6   Heart
      ASAP2   Asap2   reg         8   Lung
      ASAP3   Asap3   SCRAMBLED   5   Heart
      ASAP3   Asap3   scram       8   Heart
      ASAP3   Asap3   CANONICAL   5   Heart
      ASAP3   Asap3   reg         5   Heart", header=TRUE)
      
      merge(df[df$Organ=="Heart",], df[df$Organ=="Lung",], by=c("Human","Rat"))
      
        Human   Rat RNAtype.x Exp.x Organ.x RNAtype.y Exp.y Organ.y
      1 ASAP2 Asap2       reg     5   Heart       reg     8    Lung
      2 ASAP2 Asap2 CANONICAL     5   Heart       reg     8    Lung
      3 ASAP2 Asap2       reg     6   Heart       reg     8    Lung
      

      或者:

      genes2keep <- intersect(df[df$Organ=="Heart",]$Human, df[df$Organ=="Lung",]$Human)
      df[df$Human %in% genes2keep, ]
      
        Human   Rat   RNAtype Exp Organ
      2 ASAP2 Asap2       reg   5 Heart
      3 ASAP2 Asap2 CANONICAL   5 Heart
      4 ASAP2 Asap2       reg   6 Heart
      5 ASAP2 Asap2       reg   8  Lung
      

      【讨论】:

        【解决方案3】:

        如果您的器官列仅包含肺和心脏这两个值,这里是另一种方法:

        library(dplyr)
        
        dfsub <- df %>%
          group_by(Human) %>%
          filter(length(unique(Organ)) >= 2)
        
        #Source: local data frame [4 x 5]
        #Groups: Human
        #
        #  Human   Rat   RNAtype Exp Organ
        #1 ASAP2 Asap2       reg   5 Heart
        #2 ASAP2 Asap2 CANONICAL   5 Heart
        #3 ASAP2 Asap2       reg   6 Heart
        #4 ASAP2 Asap2       reg   8  Lung
        

        【讨论】:

        • 如果你不介意的话,从你那里偷走 uniquelength :) 至少在我想出更好的方法之前
        • @DavidArenburg,因为我们都是开源的,我想这很好(如果你发现更好的东西,请告诉我)
        【解决方案4】:

        data.table 解决方案

        library(data.table)
        setDT(df)[, indx := length(unique(Organ)) >= 2, by = Rat][indx == TRUE]
        
        ##    Human   Rat   RNAtype Exp Organ indx
        ## 1: ASAP2 Asap2       reg   5 Heart TRUE
        ## 2: ASAP2 Asap2 CANONICAL   5 Heart TRUE
        ## 3: ASAP2 Asap2       reg   6 Heart TRUE
        ## 4: ASAP2 Asap2       reg   8  Lung TRUE
        

        感谢@Arun,这里有一些更酷的data.table 解决方案

        setDT(df)[, .SD[length(unique(Organ)) >= 2L], by=Rat]
        

        或者

        setDT(df)[df[, .I[length(unique(Organ))>=2L], by=Rat]$V1]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-01
          • 2021-11-24
          • 1970-01-01
          • 2022-01-07
          • 2021-12-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-06
          相关资源
          最近更新 更多