2016-05-12 25 views
0

我的目標識別數據幀的行是要在R.R:連接在由分擔值在兩列中

兩列之間基於共享值的單個數據幀在本例中內識別「連接」的行,有是由與每個唯一片段相對應的整數標識的10個唯一片段(即,數據簇)。每行表示已經確定在彼此的特定距離閾值內的兩個段。列「segA」和「segB」之間沒有明顯的區別,它們僅用於跟蹤連接的段對。 「dist」列表示該對段之間的距離,但在這一點上並不真正需要,因爲數據幀僅包含那些被認爲「連接」的段對。

我試圖找出一種方法來識別所有在「segA」或「segB」中具有至少一個共享值的行,這表示行之間的連接段。我最初的嘗試對於循環和邏輯語句(我是R編程新手)而言已經過分複雜,所以我會非常感謝任何簡潔的解決方案!

實施例:

df = data.frame(
    segA = c(1, 1, 2, 4, 6, 7, 9), 
    segB = c(2, 3, 4, 5, 8, 8, 10), 
    dist = c(0.5321, 0.3212, 0.4351, 0.1421, 0.5125, 0.1692, 0.3218) 
) 

df 
    segA segB dist 
1 1 2 0.5321 
2 1 3 0.3212 
3 2 4 0.4351 
4 4 5 0.1421 
5 6 8 0.5125 
6 7 8 0.1692 
7 9 10 0.3218 

行1和2被連接,因爲它們都包含段 「1」。

行3和1被連接,因爲它們都包含段「2」,等等

即使行2和3不被共享段的存在直接連接,它們被連接時,整體,由通過第1行

它們的相互連接的所需的最終輸出將是這樣的:

(1) = 1, 2, 3, 4, 5 
(2) = 6, 7, 8 
(3) = 9, 10 

,其中(1),(2)和(3)代表的不同整體段和它們的部件,其是直接/相互連接。

+0

看樣子你有一個連接的網絡問題。我從來沒有使用它,但也許igraph軟件包或類似的東西會有用。 – Dave2e

+0

有時候知道問題的名稱是戰鬥的一半。謝謝你。 – Gerald

回答

0
## helper function for merging vector elements of a list 
merge.elems <- function(x,i,j) { 
    c(
     x[seq_len(i-1L)], ## before i 
     list(unique(c(x[[i]],x[[j]]))), ## combined i,j 
     x[seq_len(j-i-1L)+i], ## between i,j 
     x[seq_len(length(x)-j)+j] ## after j 
    ); 
}; ## end merge.elems() 

## initialize row groups and value groups 
rgs <- as.list(seq_len(nrow(df))); 
vgs <- do.call(Map,c(c,unname(df[1:2]))); 

## if there are 2 or more groups, exhaustively merge overlapping value group pairs 
if (length(rgs)>1L) { 
    i <- 1L; 
    j <- 2L; 
    repeat { 
     if (any(vgs[[i]]%in%vgs[[j]])) { 
      rgs <- merge.elems(rgs,i,j); 
      vgs <- merge.elems(vgs,i,j); 
      j <- i+1L; 
      if (j>length(rgs)) break; 
     } else { 
      j <- j+1L; 
      if (j>length(rgs)) { 
       i <- i+1L; 
       if (i==length(rgs)) break; 
       j <- i+1L; 
      }; ## end if 
     }; ## end if 
    }; ## end repeat 
}; ## end if 

## results 
rgs; 
## [[1]] 
## [1] 1 2 3 4 
## 
## [[2]] 
## [1] 5 6 
## 
## [[3]] 
## [1] 7 
## 
vgs; 
## [[1]] 
## [1] 1 2 3 4 5 
## 
## [[2]] 
## [1] 6 8 7 
## 
## [[3]] 
## [1] 9 10 
##