R:识别两列中共享值连接的数据帧行

时间:2016-05-12 01:47:21

标签: r dataframe aggregate connected-components

我的目标是识别" connected"基于R中两列之间的共享值的单个数据帧中的行。

在该示例中,存在10个唯一的片段(即,数据簇),其由对应于每个唯一片段的整数标识。每行表示已经确定在彼此的特定距离阈值内的两个片段。列和#34; 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)代表直接/相互连接的不同整体段及其组成部分。

1 个答案:

答案 0 :(得分:0)

bool is_valid(std::string src){
    std::stringstream ss;
    ss << src;
    double d=0;
    ss >> d; 
    if (ss){
       return true;
    }
    else{
       return false;
    }
}
## 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