R伪合并属于某个数字区域内的因子行

时间:2014-04-23 18:29:05

标签: r merge data.table intervals

我有一个复杂的合并问题,你可以希望得到一些启示。

我有两个数据框。第一个包含由数字(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中编写可以完成此任务的脚本。很感谢任何形式的帮助。

提前谢谢你。

2 个答案:

答案 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"))