1

最初のファイルの列 B のエントリが 2 番目のファイルの列 B と C の範囲に入る場合、両方のファイルに含まれるすべての情報が出力に含まれるように、2 つのファイルをマージ/結合したいと考えています。

このような:

ファイル 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 のどの行の範囲にも含まれないため、(出力ファイルから) 削除されます。

助言がありますか?

ありがとうございました!

4

3 に答える 3

1

更新: この質問は、ここに示されているよりも複雑でした。解決策はここにあります: Merge by Range in R - Applying LoopsGenomicRangesで、Bioconductorのパッケージを使用して提供されます。とても便利なパッケージ!

于 2012-08-10T00:38:29.710 に答える
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最初に、行ごとに、最初の の 2 番目の列の値を、2 番目の の 2 番目および 3 番目の列の値と比較しますdata.frame
  2. 次に、それらのいずれかが両方の条件を満たしているかどうかを確認しFALSE、最初の からそれらを削除しますdata.frame
  3. 次に、最初data.frameの列を 2 番目の列で並べ替え、2 番目の列をdata.frame"min" 一致列で並べ替えます。
  4. 最後に、最初のデータセットの値が指定された値の間にあることを確認するために、もう一度チェックを行います。そうでない場合、その行は削除されます。

さて、ここにいくつかのサンプルデータがあります。A提供されたデータとB同じです。さらなるテスト目的で変更されていますX。とYの間のマージでは、行は 1 つだけである必要があります。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
于 2012-08-07T19:44:26.490 に答える
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)で示されているように、欠落がありました。

于 2012-08-07T18:24:25.797 に答える