R中的匹配范围合并

时间:2012-08-07 17:40:47

标签: arrays r merge range match

我想合并/合并两个文件,这样如果我的第一个文件的B列中的条目属于我的第二个文件中的列B和C的范围,则输出将包含两个文件中包含的所有信息文件。

像这样:

档案1

     A      B
    rs10    23353
    rs100   10000
    rs234   54440

文件2

    A        B      C
    E235    20000   30000
    E255    50000   60000

其中,因为23353介于20000和30000之间,而54440介于50000和60000之间,输出文件将如下所示:

rs      23353   E235    20000   30000
rs234   54440   E255    50000   60000

和rs100将被删除(来自输出文件),因为它不属于文件2中任何行的范围。

有什么建议吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

这样的事情应该可以解决问题。你可能会使它更简洁,但要阐明我所做的所有步骤过于明显。

NewMatrixCol1 <- c()
NewMatrixCol2 <- c()
NewMatrixCol3 <- c()
NewMatrixCol4 <- c()
NewMatrixCol5 <- c()

for (i in 1:length(file1$A)) {
    for (j in 1:length(file2$A)) {
        LowNumber <- file2$B[j]
        HighNumber <- file2$C[j]
        if (LowNumber <= file1$B[i] & file1$B[i]  <= HighNumber) {
            append(NewMatrixCol1, file1$A[i])
            append(NewMatrixCol2, file1$B[i])
            append(NewMatrixCol3, file2$A[j])
            append(NewMatrixCol4, file2$B[j])
            append(NewMatrixCol5, file2$C[j])
        } else {}
    }
}

dataframe <- data.frame(Col1 = NewMatrixCol1, Col2 = NewMatrixCol2, Col3 = NewMatrixCol3, Col4 = NewMatrixCol4, Col5 = NewMatrixCol5)

EDIT1:我误解了这个问题,现在正在研究它。

EDIT2:这个新的解决方案应该按照指示工作。

EDIT3:缺少),如mfk534所示。

答案 1 :(得分:1)

我看到你已经接受了答案,但这是另一种可能的解决方案。

这个功能只是被黑客攻击,但可以更多地进行处理以使其更加通用化。

myfun = function(DATA1, DATA2, MATCH1, MIN, MAX) {
  temp = sapply(1:nrow(DATA2), 
                function(x) DATA1[[MATCH1]] >= DATA2[[MIN]][x] &
                  DATA1[[MATCH1]] <= DATA2[[MAX]][x])
  if (isTRUE(any(rowSums(temp) == 0))) {
    temp1 = DATA1[-(which(rowSums(temp) == 0)), ]
  }
  OUT = cbind(temp1[order(temp1[[MATCH1]]), ], 
              DATA2[order(DATA2[[MIN]]), ], row.names=NULL)
  condition = ((OUT[4] <= OUT[2] & OUT[2] <= OUT[5]) == 0)
  if (isTRUE(any(condition))) {
    OUT[-which(condition), ]
  } else {
    OUT
  }
}

这是函数的作用:

  1. 它首先逐行比较第一个data.frame第二列中的值与第二个data.frame的第二列和第三列中的值。
  2. 然后检查以查找是否有任何条件FALSE,并从第一个data.frame中删除它们。
  3. 然后,它将第一列data.frame排序,第二列排序data.frame
  4. 最后,它再做一次检查以确保第一个数据集中的值介于提供的值之间;如果没有,该行将被删除。
  5. 现在,这是一些示例数据。 AB与您提供的数据相同。 XY已更改,以便进一步测试。在XY之间的合并中,应该只有一行。

    A = read.table(header=TRUE, text="A      B
        rs10    23353
        rs100   10000
        rs234   54440")
    
    B = read.table(header=TRUE, text="A        B      C
        E235    20000   30000
        E255    50000   60000")
    
    X = A[c(3, 1, 2), ]
    X[1, 2] = 57000
    Y = B
    Y[2, 3] = 55000
    

    以下是使用函数和输出的方法。

    myfun(A, B, 2, 2, 3)
    #       A     B    A     B     C
    # 1  rs10 23353 E235 20000 30000
    # 2 rs234 54440 E255 50000 60000
    myfun(X, Y, 2, 2, 3)
    #      A     B    A     B     C
    # 1 rs10 23353 E235 20000 30000
    

答案 2 :(得分:0)

更新:这个问题比这里指出的要复杂得多。可在此处找到解决方案:Merge by Range in R - Applying Loops,并使用Bioconductor中的GenomicRanges包进行传递。非常有用的包!