【问题标题】:How to extract rows with specific columns and values between two data tables?如何在两个数据表之间提取具有特定列和值的行?
【发布时间】:2019-12-11 02:42:59
【问题描述】:

我有两个排序的数据表(A 和 B),在表 A 中,前 3 列是基因组坐标。 我喜欢从 A 表中提取一些特定的行,但基于 B 表的一些常见列/值。

例如:首先我想匹配A表和B表的'ID'列,然后如果B表的'strand'列中有1值,则选择那些行(从A表)在 A 和 B 表的“值”列和之前的坐标中具有相同的值(第一次匹配)。但是如果 B 表的 'strand' 列中有 - 1 值,则选择 A 和 B 表的 'Value' 列中具有相同值(最后匹配)的那些行(来自 A 表)和坐标后。

mydf1 <- structure(list(chr = c("17", "17", "17", "17", "17", "17", "17", "8", "8", "8", "8", "8", "8", "8", "X", "X", "X", "X", "X", "10", "10", "10", "10", "10", "10", "10", "10", "10"), start = c(50094737L, 50096132L, 50097423L, 50105371L, 50109957L, 50109957L, 50109957L, 22987417L, 22999579L, 23004425L, 23005372L, 23006728L, 23015638L, 23017252L, 119539386L, 119541328L, 119544353L, 119560268L, 119565232L, 14518560L, 14521158L, 14521869L, 14530332L, 14553322L, 14571763L, 14572229L, 14667634L, 14774253L), end = c(50094898L, 50096286L, 50097564L, 50105442L, 50111058L, 50111368L, 50112152L, 22987563L, 23000105L, 23004626L, 23005475L, 23007746L, 23015743L, 23020199L, 119539789L, 119541420L, 119544491L, 119560385L, 119565401L, 14521306L, 14521306L, 14522019L, 14530515L, 14553387L, 14572189L, 14572314L, 14667691L, 14774897L), Value = c(1L, 2L, 3L, 3L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 8L, 8L, 2L, 2L, 1L, 1L, 1L), Tx = c("ENST00000007708", "ENST00000007708", "ENST00000007708,ENST00000503176,ENST00000614357", "ENST00000007708,ENST00000503176,ENST00000614357", "ENST00000007708", "ENST00000614357", "ENST00000503176", "ENST00000519685", "ENST00000251822", "ENST00000251822,ENST00000519685", "ENST00000251822,ENST00000519685", "ENST00000251822,ENST00000519685", "ENST00000251822,ENST00000519685", "ENST00000251822", "ENST00000644802", "ENST00000320339,ENST00000644802", "ENST00000320339,ENST00000644802", "ENST00000320339,ENST00000644802", "ENST00000644802", "ENST00000181796", "ENST00000479731", "ENST00000181796,ENST00000378458,ENST00000378467,ENST00000378470,ENST00000468747,ENST00000478076,ENST00000479731,ENST00000622567", "ENST00000181796,ENST00000378458,ENST00000378467,ENST00000378470,ENST00000468747,ENST00000478076,ENST00000479731,ENST00000622567", "ENST00000378458,ENST00000378467", "ENST00000378458,ENST00000622567", "ENST00000479731", "ENST00000181796", "ENST00000181796"), ID = c("ENSG00000005882", "ENSG00000005882", "ENSG00000005882", "ENSG00000005882", "ENSG00000005882", "ENSG00000005882", "ENSG00000005882", "ENSG00000008853", "ENSG00000008853", "ENSG00000008853", "ENSG00000008853", "ENSG00000008853", "ENSG00000008853", "ENSG00000008853", "ENSG00000018610", "ENSG00000018610", "ENSG00000018610", "ENSG00000018610", "ENSG00000018610", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809")), class = "data.frame", row.names = c(NA, 28L))
mydf2 <- structure(list(ID = c("ENSG00000005882", "ENSG00000008853", "ENSG00000018610", "ENSG00000065809"), name = c("PDK2", "RHOBTB2", "CXorf56", "FAM107B"), strand = c(1L, 1L, -1L, -1L), Value = c(3L, 2L, 2L, 8L)), class = "data.frame", row.names = c(NA, 4L))

输入 A:

mydf1

chr start       end       Value Tx              ID
17  50094737    50094898    1   ENST00000007708 ENSG00000005882 
17  50096132    50096286    2   ENST00000007708 ENSG00000005882 
17  50097423    50097564    3   ENST00000007708,ENST00000503176,ENST00000614357 ENSG00000005882
17  50105371    50105442    3   ENST00000007708,ENST00000503176,ENST00000614357 ENSG00000005882
17  50109957    50111058    1   ENST00000007708 ENSG00000005882 
17  50109957    50111368    2   ENST00000614357 ENSG00000005882 
17  50109957    50112152    1   ENST00000503176 ENSG00000005882 
8   22987417    22987563    2   ENST00000519685 ENSG00000008853 
8   22999579    23000105    1   ENST00000251822 ENSG00000008853 
8   23004425    23004626    2   ENST00000251822,ENST00000519685 ENSG00000008853
8   23005372    23005475    2   ENST00000251822,ENST00000519685 ENSG00000008853
8   23006728    23007746    2   ENST00000251822,ENST00000519685 ENSG00000008853
8   23015638    23015743    2   ENST00000251822,ENST00000519685 ENSG00000008853
8   23017252    23020199    1   ENST00000251822 ENSG00000008853 
X   119539386   119539789   1   ENST00000644802 ENSG00000018610 
X   119541328   119541420   2   ENST00000320339,ENST00000644802 ENSG00000018610
X   119544353   119544491   2   ENST00000320339,ENST00000644802 ENSG00000018610
X   119560268   119560385   2   ENST00000320339,ENST00000644802 ENSG00000018610
X   119565232   119565401   1   ENST00000644802 ENSG00000018610 
10  14518560    14521306    1   ENST00000181796 ENSG00000065809 
10  14521158    14521306    1   ENST00000479731 ENSG00000065809 
10  14521869    14522019    8    ENST00000181796,ENST00000378458,ENST00000378467,ENST00000378470,ENST00000468747,ENST00000478076,ENST00000479731,ENST00000622567    ENSG00000065809
10  14530332    14530515    8    ENST00000181796,ENST00000378458,ENST00000378467,ENST00000378470,ENST00000468747,ENST00000478076,ENST00000479731,ENST00000622567    ENSG00000065809
10  14553322    14553387    2   ENST00000378458,ENST00000378467 ENSG00000065809
10  14571763    14572189    2   ENST00000378458,ENST00000622567 ENSG00000065809
10  14572229    14572314    1   ENST00000479731 ENSG00000065809 
10  14667634    14667691    1   ENST00000181796 ENSG00000065809 
10  14774253    14774897    1   ENST00000181796 ENSG00000065809 

输入 B:

mydf2 

ID              name  strand Value
ENSG00000005882 PDK2     1  3
ENSG00000008853 RHOBTB2  1  2
ENSG00000018610 CXorf56 -1  2
ENSG00000065809 FAM107B -1  8

愿望输出:

17  50094737    50094898    1   ENST00000007708 ENSG00000005882 
17  50096132    50096286    2   ENST00000007708 ENSG00000005882 
17  50097423    50097564    3   ENST00000007708,ENST00000503176,ENST00000614357 ENSG00000005882
8   22987417    22987563    2   ENST00000519685 ENSG00000008853 
X   119560268   119560385   2   ENST00000320339,ENST00000644802 ENSG00000018610
X   119565232   119565401   1   ENST00000644802 ENSG00000018610 
10  14530332    14530515    8   ENST00000181796,ENST00000378458,ENST00000378467,ENST00000378470,ENST00000468747,ENST00000478076,ENST00000479731,ENST00000622567 ENSG00000065809
10  14553322    14553387    2   ENST00000378458,ENST00000378467 ENSG00000065809
10  14571763    14572189    2   ENST00000378458,ENST00000622567 ENSG00000065809
10  14572229    14572314    1   ENST00000479731 ENSG00000065809 
10  14667634    14667691    1   ENST00000181796 ENSG00000065809 
10  14774253    14774897    1   ENST00000181796 ENSG00000065809 

我尝试过使用dyplrifelse,但我无法得到我想要的。

非常感谢任何可能的解决方案!

【问题讨论】:

  • 嘿,你能为你的每个表提供一个dput() 输出吗?
  • 你能用列名代替“第六列”、“第四列”等吗?似乎第一步是 left_join 表 A 和 B,这使得跟踪列顺序有点困难,而您正在使用 dplyr 鼓励独占使用列名。
  • 谢谢,我已经更新了列名。
  • 你能用“之前/之后的坐标”具体说明你的意思吗?
  • idownvotedbecau.se/unclearquestion idownvotedbecau.se/toomuchcode idownvotedbecau.se/unreadablecode 请把问题说清楚。看起来很有趣,但真的不清楚你在问什么。

标签: r dataframe if-statement dplyr


【解决方案1】:

如果没有提供您的数据帧的dput() 输出,这是相当困难的,但我会尝试一下:

t <- left_join(A, B, by=c(ID, Value)) # Join the two tables together by ID and Value

first_occ <- t %>% group_by(strand) %>% filter(row_number() == min(row_number())) # select first occurrence
last_occ <- t %>% group_by(strand) %>% filter(row_number() == max(row_number())) # select last occurrence

【讨论】:

  • 非常感谢。它看起来不错,但我希望坐标低于第一个 ID 匹配(如果链为 1)并且坐标大于最后一个 ID 匹配(如果链为 -1)
【解决方案2】:

我冒昧地将您使用 this unfortunately little know awesome package 的示例数据帧转换为可重现的示例。不幸的是,您的问题有些晦涩难懂,但听起来通常很有趣,可以继续研究。

mydf1 <- structure(list(chr = c("17", "17", "17", "17", "17", "17", "17", "8", "8", "8", "8", "8", "8", "8", "X", "X", "X", "X", "X", "10", "10", "10", "10", "10", "10", "10", "10", "10"), start = c(50094737L, 50096132L, 50097423L, 50105371L, 50109957L, 50109957L, 50109957L, 22987417L, 22999579L, 23004425L, 23005372L, 23006728L, 23015638L, 23017252L, 119539386L, 119541328L, 119544353L, 119560268L, 119565232L, 14518560L, 14521158L, 14521869L, 14530332L, 14553322L, 14571763L, 14572229L, 14667634L, 14774253L), end = c(50094898L, 50096286L, 50097564L, 50105442L, 50111058L, 50111368L, 50112152L, 22987563L, 23000105L, 23004626L, 23005475L, 23007746L, 23015743L, 23020199L, 119539789L, 119541420L, 119544491L, 119560385L, 119565401L, 14521306L, 14521306L, 14522019L, 14530515L, 14553387L, 14572189L, 14572314L, 14667691L, 14774897L), Value = c(1L, 2L, 3L, 3L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 8L, 8L, 2L, 2L, 1L, 1L, 1L), Tx = c("ENST00000007708", "ENST00000007708", "ENST00000007708,ENST00000503176,ENST00000614357", "ENST00000007708,ENST00000503176,ENST00000614357", "ENST00000007708", "ENST00000614357", "ENST00000503176", "ENST00000519685", "ENST00000251822", "ENST00000251822,ENST00000519685", "ENST00000251822,ENST00000519685", "ENST00000251822,ENST00000519685", "ENST00000251822,ENST00000519685", "ENST00000251822", "ENST00000644802", "ENST00000320339,ENST00000644802", "ENST00000320339,ENST00000644802", "ENST00000320339,ENST00000644802", "ENST00000644802", "ENST00000181796", "ENST00000479731", "ENST00000181796,ENST00000378458,ENST00000378467,ENST00000378470,ENST00000468747,ENST00000478076,ENST00000479731,ENST00000622567", "ENST00000181796,ENST00000378458,ENST00000378467,ENST00000378470,ENST00000468747,ENST00000478076,ENST00000479731,ENST00000622567", "ENST00000378458,ENST00000378467", "ENST00000378458,ENST00000622567", "ENST00000479731", "ENST00000181796", "ENST00000181796"), ID = c("ENSG00000005882", "ENSG00000005882", "ENSG00000005882", "ENSG00000005882", "ENSG00000005882", "ENSG00000005882", "ENSG00000005882", "ENSG00000008853", "ENSG00000008853", "ENSG00000008853", "ENSG00000008853", "ENSG00000008853", "ENSG00000008853", "ENSG00000008853", "ENSG00000018610", "ENSG00000018610", "ENSG00000018610", "ENSG00000018610", "ENSG00000018610", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809", "ENSG00000065809")), class = "data.frame", row.names = c(NA, 28L))
mydf2 <- structure(list(ID = c("ENSG00000005882", "ENSG00000008853", "ENSG00000018610", "ENSG00000065809"), name = c("PDK2", "RHOBTB2", "CXorf56", "FAM107B"), strand = c(1L, 1L, -1L, -1L), Value = c(3L, 2L, 2L, 8L)), class = "data.frame", row.names = c(NA, 4L))

library(tidyverse)

mymerge <- 
  left_join(mydf1, mydf2, by = c('ID', 'Value')) %>% 
  slice(c(which(strand == 1), which(strand == 1)-1,
        which(strand == -1), which(strand == -1)+1)) %>% 
    distinct %>% # there will be some duplicate rows, remove them
    select(-Tx) %>% arrange(chr) # both steps just for demonstration

mymerge  
#>    chr     start       end Value              ID    name strand
#> 1   10  14521869  14522019     8 ENSG00000065809 FAM107B     -1
#> 2   10  14530332  14530515     8 ENSG00000065809 FAM107B     -1
#> 3   10  14553322  14553387     2 ENSG00000065809    <NA>     NA
#> 4   17  50097423  50097564     3 ENSG00000005882    PDK2      1
#> 5   17  50105371  50105442     3 ENSG00000005882    PDK2      1
#> 6   17  50096132  50096286     2 ENSG00000005882    <NA>     NA
#> 7   17  50109957  50112152     1 ENSG00000005882    <NA>     NA
#> 8    8  22987417  22987563     2 ENSG00000008853 RHOBTB2      1
#> 9    8  23004425  23004626     2 ENSG00000008853 RHOBTB2      1
#> 10   8  23005372  23005475     2 ENSG00000008853 RHOBTB2      1
#> 11   8  23006728  23007746     2 ENSG00000008853 RHOBTB2      1
#> 12   8  23015638  23015743     2 ENSG00000008853 RHOBTB2      1
#> 13   8  22999579  23000105     1 ENSG00000008853    <NA>     NA
#> 14   X 119541328 119541420     2 ENSG00000018610 CXorf56     -1
#> 15   X 119544353 119544491     2 ENSG00000018610 CXorf56     -1
#> 16   X 119560268 119560385     2 ENSG00000018610 CXorf56     -1
#> 17   X 119565232 119565401     1 ENSG00000018610    <NA>     NA

现在,按照@Steve 的建议合并后,我使用slice 创建了索引。 您想要的输出与我的不同 - 这是因为我不太明白您的意思。我的解决方案可能并不完全是您想要的,或者您想要的输出并不完全是您想要的。

reprex package (v0.3.0) 于 2019 年 8 月 2 日创建

【讨论】:

  • 不知道read.so 包确实很棒,非常感谢分享!
【解决方案3】:

如果我理解正确,OP 想要为每个匹配的 IDmydf1 中提取所有行

  • ID 组的第一行到第一个匹配的Value if strand == 1
  • 如果strand == -1,则从最后一个匹配的ValueID 组的最后一行。

以下方法使用data.table 包提供的非等连接

library(data.table)

# coerce to data.table and append row number
setDT(mydf1)[, rn := .I]
setDT(mydf2)

# pick first rows
tmpf <- mydf1[mydf2[strand == 1], on = .(ID, Value), mult = "first", .(ID, rn)]
resf <- mydf1[tmpf, on = .(ID, rn <= rn)]

# pick last rows
tmpl <- mydf1[mydf2[strand == -1], on = .(ID, Value), mult = "last", .(ID, rn)]
resl <- mydf1[tmpl, on = .(ID, rn >= rn)]

# combine both partial results, remove row numbers
rbind(resf, resl)[, rn:= NULL][]
    chr     start       end Value                                                 Tx              ID
 1:  17  50094737  50094898     1                                    ENST00000007708 ENSG00000005882
 2:  17  50096132  50096286     2                                    ENST00000007708 ENSG00000005882
 3:  17  50097423  50097564     3    ENST00000007708,ENST00000503176,ENST00000614357 ENSG00000005882
 4:   8  22987417  22987563     2                                    ENST00000519685 ENSG00000008853
 5:   X 119560268 119560385     2                    ENST00000320339,ENST00000644802 ENSG00000018610
 6:   X 119565232 119565401     1                                    ENST00000644802 ENSG00000018610
 7:  10  14530332  14530515     8 ENST00000181796,ENST00000378458,ENST00000378467... ENSG00000065809
 8:  10  14553322  14553387     2                    ENST00000378458,ENST00000378467 ENSG00000065809
 9:  10  14571763  14572189     2                    ENST00000378458,ENST00000622567 ENSG00000065809
10:  10  14572229  14572314     1                                    ENST00000479731 ENSG00000065809
11:  10  14667634  14667691     1                                    ENST00000181796 ENSG00000065809
12:  10  14774253  14774897     1                                    ENST00000181796 ENSG00000065809

说明

待完成

数据

data.table 中的 fread() 函数也能够读取 OP 提供的数据:

library(data.table)

mydf1 <- fread( "chr start       end       Value Tx              ID
17  50094737    50094898    1   ENST00000007708 ENSG00000005882 
17  50096132    50096286    2   ENST00000007708 ENSG00000005882 
17  50097423    50097564    3   ENST00000007708,ENST00000503176,ENST00000614357 ENSG00000005882
17  50105371    50105442    3   ENST00000007708,ENST00000503176,ENST00000614357 ENSG00000005882
17  50109957    50111058    1   ENST00000007708 ENSG00000005882 
17  50109957    50111368    2   ENST00000614357 ENSG00000005882 
17  50109957    50112152    1   ENST00000503176 ENSG00000005882 
8   22987417    22987563    2   ENST00000519685 ENSG00000008853 
8   22999579    23000105    1   ENST00000251822 ENSG00000008853 
8   23004425    23004626    2   ENST00000251822,ENST00000519685 ENSG00000008853
8   23005372    23005475    2   ENST00000251822,ENST00000519685 ENSG00000008853
8   23006728    23007746    2   ENST00000251822,ENST00000519685 ENSG00000008853
8   23015638    23015743    2   ENST00000251822,ENST00000519685 ENSG00000008853
8   23017252    23020199    1   ENST00000251822 ENSG00000008853 
X   119539386   119539789   1   ENST00000644802 ENSG00000018610 
X   119541328   119541420   2   ENST00000320339,ENST00000644802 ENSG00000018610
X   119544353   119544491   2   ENST00000320339,ENST00000644802 ENSG00000018610
X   119560268   119560385   2   ENST00000320339,ENST00000644802 ENSG00000018610
X   119565232   119565401   1   ENST00000644802 ENSG00000018610 
10  14518560    14521306    1   ENST00000181796 ENSG00000065809 
10  14521158    14521306    1   ENST00000479731 ENSG00000065809 
10  14521869    14522019    8    ENST00000181796,ENST00000378458,ENST00000378467,ENST00000378470,ENST00000468747,ENST00000478076,ENST00000479731,ENST00000622567    ENSG00000065809
10  14530332    14530515    8    ENST00000181796,ENST00000378458,ENST00000378467,ENST00000378470,ENST00000468747,ENST00000478076,ENST00000479731,ENST00000622567    ENSG00000065809
10  14553322    14553387    2   ENST00000378458,ENST00000378467 ENSG00000065809
10  14571763    14572189    2   ENST00000378458,ENST00000622567 ENSG00000065809
10  14572229    14572314    1   ENST00000479731 ENSG00000065809 
10  14667634    14667691    1   ENST00000181796 ENSG00000065809 
10  14774253    14774897    1   ENST00000181796 ENSG00000065809 ")

mydf2 <- fread("ID              name  strand Value
ENSG00000005882 PDK2     1  3
ENSG00000008853 RHOBTB2  1  2
ENSG00000018610 CXorf56 -1  2
ENSG00000065809 FAM107B -1  8")

【讨论】:

  • 非常感谢!这正是我想要的!
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 2018-03-28
相关资源
最近更新 更多