根据一列中的多个值创建行的子集

时间:2014-07-29 19:48:25

标签: r subset

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

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。

4 个答案:

答案 0 :(得分:3)

这是另一种策略:

> 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

答案 1 :(得分: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

答案 2 :(得分:2)

如果你的风琴专栏只包含龙和心这两个值,这是另一种方法:

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

答案 3 :(得分:2)

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]