R:

2016-05-12 3 views
0

私の目的は、2列に価値観によって接続識別データフレームの行があり、この例ではR.R:

に二つの列の間で共有さ値に基づいて、単一のデータ・フレーム内の「接続」の行を識別することです各ユニークなセグメントに対応する整数によって識別される10のユニークなセグメント(すなわち、データのクラスタ)である。各行は、互いに所定の距離閾値内にあると既に決定された2つのセグメントを表す。列「segA」と「segB」の間には大きな違いはなく、単に接続されているセグメントのペアを追跡するために使用されます。列「dist」は、一対のセグメントの間の距離を表すが、データフレームは「接続された」とみなされるセグメントのペアのみを含むので、この時点で実際には必要ではない。

"segA"または "segB"に少なくとも1つの共有値を持つすべての行を識別する方法を理解しようとしています。これは行間の接続セグメントを示しています。

私は最初の試みがループと論理ステートメントのために混乱しています(私はRプログラミングの初心者です)ので、私は非常に簡潔なソリューションに感謝します!

例:彼らの両方がセグメント "1" が含まれているため

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が接続されています。彼らの両方が含まれているため

行3と1が接続されているセグメント「2」、等

行2及び3は、直接共有セグメントの存在によって接続されていないとしても、それらは、全体として、によって接続されている

行を通じて相互接続1.

所望の最終的な出力のようなものであろう:

(1)、(2)、及び(3)は、異なる全体的なセグメントとそのコンポーネントを表す
(1) = 1, 2, 3, 4, 5 
(2) = 6, 7, 8 
(3) = 9, 10 

直接/相互に接続されています。

+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 
##