我有一个复杂的合并问题,你可以希望得到一些启示。
我有两个数据框。第一个包含由数字(1,2,3等)表示的波长区域,其中在由颜色(RED,BLUE等)表示的那些区域内找到子区域。它们的波长中点位置(中间),开始位置(开始)和结束位置(结束)。
>df1
sub_region region mid start end
RED 1 15 10 20
GREEN 3 3 1 5
BLUE 2 310 300 320
(etc... ~50,000 rows total)
第二个包含那些颜色的描述(非常,轻微等),目录参考ID(GFHHTSTGGSH,GFDDDRDRDD等),与df1匹配的区域(1,2,3等),以及它们自己的精确波长起始和终止位置,一些在df1的位置。
>df2
region start end colorDescrip refID
2 312 318 VERY GFHHTSTGGSH
1 55 76 SLIGHTY GFDDDRDRDD
(etc... ~500,000 rows total)
我想创建一个数据框(df3),其中df1和df2(1,2,3等)的区域在匹配区域行中匹配AND,颜色描述' s(colorDescrip)开始,来自df2的结束波长在df1的起始和结束波长之间下降(例如df2的行1和df1的行3)。生成的df3只需要有三列:" sub_region"," colorDescrip"和" refID"。
以下是一个示例。在给出的示例中,唯一适合两个周长的示例是df2的第1行与df1的第3行匹配:
>df3
sub_region colorDescrip refID
BLUE VERY GFHHTSTGGSH
同样,区域匹配(两者都是区域2)和#34的开始/结束;非常" (312,318)落在"蓝色"的开始/结束波长范围内。 (300,320)。
我很难在R中编写可以完成此任务的脚本。很感谢任何形式的帮助。
提前谢谢你。
答案 0 :(得分:3)
我相信这可以通过两个滚动连接的组合来实现,这是data.table
的一个功能。
将两个数据集定义为data.table
,并按区域开始(下限)设置匹配它们的键。这样,df2
中的每种颜色都会匹配df1
中较小的下一个开头。
df1 <- data.table(df1, key='region,start')
df2 <- data.table(df2, key='region,start')
df.start <- df1[df2, roll=T, allow.cartesian=TRUE]
我们最后做同样的事情,但是我们改变了匹配的方向(频谱的下一个最大的上端)
setkey(df1, region, end) ## reset the keys
setkey(df2, region, end)
df.end <- df1[df2, roll=-Inf, allow.cartesian=TRUE]
您想要的解决方案是两个数据集之间的交集。这可以通过内部联接(在数据库术语中)找到。我们首先需要设置密钥,以便它们唯一地识别每个组合。
setkey(df.start, sub_region, refID)
setkey(df.end, sub_region, refID)
df.start[df.end, list(colorDescrip), nomatch=0]
最后一行返回您想要的结果,您可以将其保存在d3
中。如果您以前从未见过它,语法可能会显得有点神秘,但data.table
值得研究。
修改:注意到有关region
匹配和更新代码的部分以反映该内容。
答案 1 :(得分:-1)
这是一次尝试:
subset(merge(df1,df2,by="region"),
start.y>start.x & end.y<end.x,
select=c("sub_region","colorDescrip","refID"))