如何基于R中的另一个数据框过滤和子集数据框

时间:2019-05-09 12:27:02

标签: r dataframe

尽管有许多与此类似的问题,但我一直无法在R中专门找到该问题的答案,因此我不确定从何处开始。我有2个数据集:

数据1:

Chr Start   End   rssnp1        Type    gene
1   1244733 1244734 rs2286773   LD_SNP  ACE
1   1257536 1257436 rs301159    LD_SNP  CPEB4
1   1252336 1252336 rs2286773   Sentinel    CPEB4
1   1252343 1252343 rs301159    LD_SNP  CPEB4
1   1254841 1254841 rs301159    LD_SNP  CPEB4
1   1256703 1267404 rs301159    LD_SNP  CPEB4
1   1269246 1269246 rs301159    LD_SNP  CPEB4
1   1370168 1370168 rs301159    LD_SNP  GLUPA1
1   1371824 1371824 rs301159    LD_SNP  GLUPA1
1   1372591 1372591 rs301159    LD_SNP  GLUPA1

数据2:

    gene
    CPEB4
    GML
    TBX2
    PNKD
    JMJD1C
    SKI
    MYH11

Data2是机器学习(已被分类为影响疾病的基因)的输出。

我正在寻找从Data2中选择一个基因,在Data1中找到它,特别是找到类型列为'Sentinel'的基因行,然后根据该前哨基因的rssnp1列过滤Data1。

例如,如果我在Data1中搜索CPEB4基因,发现其Sentinel基因rssnp1(rs2286773)要通过输出进行过滤,则为:

Chr Start   End    rssnp1       Type     gene
1   1243933 1243934 rs2286773   LD_SNP  ACAP3
1   1254436 1254436 rs2286773   Sentinel    CPEB4

到目前为止,我已经研究过使用merge,filter()和subset(),但是由于我有很多步骤,我应该尝试在for循环中使用它们吗?有更好的功能吗?

我是R的新手,所以并没有取得太大进展,例如,我尝试过合并数据集:

merged <- merge(data1, data2, by='gene', all='TRUE')

然后可以在excel手动过滤中使用,但是理想情况下,我想进一步自动化它,因此向正确方向提供的任何建议/帮助都将受到赞赏。

2 个答案:

答案 0 :(得分:1)

一种选择是在{Type}中将full_join值的filterany后的'rssnp1'分组为'Sentinel'

library(dplyr)
full_join(data1, data2, by = 'gene') %>% 
     group_by(rssnp1) %>% 
     filter(any(Type == "Sentinel")) #or
     #filter("Sentinel" %in% Type)
# A tibble: 2 x 6
# Groups:   rssnp1 [1]
#    Chr   Start     End rssnp1    Type     gene 
#  <int>   <int>   <int> <chr>     <chr>    <chr>
#1     1 1244733 1244734 rs2286773 LD_SNP   ACE  
#2     1 1252336 1252336 rs2286773 Sentinel CPEB4

或者使用OP的代码,可以使用ave

对其进行进一步扩展。
i1 <-  with(merged, ave(Type %in% "Sentinel", rssnp1, FUN = any))
merged[i1,]

数据

data1 <- structure(list(Chr = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L
), Start = c(1244733L, 1257536L, 1252336L, 1252343L, 1254841L, 
1256703L, 1269246L, 1370168L, 1371824L, 1372591L), End = c(1244734L, 
1257436L, 1252336L, 1252343L, 1254841L, 1267404L, 1269246L, 1370168L, 
1371824L, 1372591L), rssnp1 = c("rs2286773", "rs301159", "rs2286773", 
"rs301159", "rs301159", "rs301159", "rs301159", "rs301159", "rs301159", 
"rs301159"), Type = c("LD_SNP", "LD_SNP", "Sentinel", "LD_SNP", 
"LD_SNP", "LD_SNP", "LD_SNP", "LD_SNP", "LD_SNP", "LD_SNP"), 
    gene = c("ACE", "CPEB4", "CPEB4", "CPEB4", "CPEB4", "CPEB4", 
    "CPEB4", "GLUPA1", "GLUPA1", "GLUPA1")),
    class = "data.frame", row.names = c(NA, 
-10L))

data2 <- structure(list(gene = c("CPEB4", "GML", "TBX2", "PNKD", "JMJD1C", 
"SKI", "MYH11")), class = "data.frame", row.names = c(NA, -7L
))

答案 1 :(得分:1)

我假设您想从data2中传递每个基因,并从data1中获取它们的相应数据。希望下面的代码有帮助。

library(dplyr)
getFromData1 <- function(geneFromData2 = NULL) {
  if (is.null(geneFromData2)) return()
  geneSentinelSNP <- (data1 %>% filter(Type == "Sentinel" & gene == geneFromData2))$rssnp1
  data1 %>% filter(rssnp1 == geneSentinelSNP)
}

getFromData1(geneFromData2 = "CPEB4")

您还可以在getFromData1中调用lapply函数,以便获得数据帧列表,data2中每个基因一个。

lapply(data2$gene, getFromData1)