可怕的标题问题,但这是我想要解决的问题。对于表1,我想添加“BETWEEN”列,以验证表2中相应“BIN”的“POSITION”是否介于“START”和“STOP”值之间。

表1 。 BIN的名称(字符)和POSITION(数字)中的位置:

  BIN    POSITION
    1          12
    1          52
    1          86
    7           6
    7          22
    X         112
    X         139
   MT           3
   MT          26

表2 :BIN名称(字符)以及START和STOP位置(数字)
  BIN    START    STOP
    1        2      64
    1       90     110
    7       20     100
    7      105     200
    X        1       5
   MT        1    1000

和期望的结果-表1中带有“BETWEEN”:
CHROM    POSITION      BETWEEN
    1          12         TRUE
    1          52         TRUE
    1          86        FALSE
    7           6        FALSE
    7          22         TRUE
    X         112        FALSE
    X         139        FALSE
   MT           3         TRUE
   MT          26         TRUE

我的表1大约有4,000,000行,表2大约有500,000行,我想到的一切都很慢。

作为较大表的示例,请使用以下命令:
positions <- seq(1,100000,10)
bins <- c("A","B","C","D","E","F","G","H","I","J")

tab1 <- data.table(bin = rep(bins,1,each=length(positions)), pos = rep(positions,10))

tab2 <- data.table(bin = rep(bins,1,each=2000), start = seq(5,100000,50), stop = start+25)

所需的输出将是:
tab1
        bin   pos    between
     1:   A     1    FALSE
     2:   A    11    TRUE
     3:   A    21    TRUE
     4:   A    31    FALSE
     5:   A    41    FALSE

最佳答案

以下方法要求对于给定的垃圾箱,垃圾箱是互斥的。 (例如,您不能使bin A的边界为1-5,而另一个bin A的边界为4-8。)此外,我对示例进行了一些修改。

positions <- seq(1,100000,10)
bins <- c("A","B","C","D","E","F","G","H","I","J")
tab1 <- data.table(bin = rep(bins,1,each=length(positions)), pos = rep(positions,10))
setkey(tab1,"bin","pos")

tab2 <- data.table(bin = rep(bins,1,each=2000), start = seq(5,100000,50))
tab2[, end := start+25]

tab2[,pos:=start]
setkey(tab2,"bin","pos")
x<-tab2[tab1, roll=TRUE, nomatch=0]

tab2[,pos:=end]
setkey(tab2,"bin","pos")
y<-tab2[tab1, roll=-Inf, nomatch=0]

setkey(x,"bin","pos","start")
setkey(y,"bin","pos","start")
inBin<-x[y,nomatch=0]
inBin[, between:=TRUE]

setkey(tab1,"bin","pos")
setkey(inBin,"bin","pos")

result<-inBin[,list(bin,pos,between)][tab1]
result[is.na(between), between:=FALSE]

我现在没有时间深入解释我的解决方案。相反,我将采取便宜的方法,并请您研究data.table的roll参数。上面的基本方法是,我要加入tab1和tab2,将pos向前滚动到最近的结束边界。然后,我加入t​​ab1和tab2,将pos向后滚动到最近的起始边界。然后,我对这两个集合进行内部联接,使我在tab1中的所有行都落在bin的范围内。从那时起,这只是艰巨的工作。

关于r - 用R数据检查一个表(X)中的值是否在另一表(Y)中两列的值之间。,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24878028/

10-12 17:36
查看更多