从两个Id列创建superID列

ind*_*til 1 r dataframe

我创建了一个数据框

data <- data.frame(a=c(1,1,2,2,3,3,4,5), b=c(1,2,2,3,3,4,5,6))

    a   b
    1   1
    1   2
    2   2
    2   3
    3   3
    3   4
    4   5
    5   6
Run Code Online (Sandbox Code Playgroud)

现在我想生成主列C如下:

    a   b  c
    1   1  1
    1   2  1
    2   2  1
    2   3  1
    3   3  1
    3   4  1
    4   5  2
    5   6  3
Run Code Online (Sandbox Code Playgroud)

这通常是从其中间id更新列a和列b的值(ID).例如具有1个对应的值列b是1,现在搜索这在具有1的所有值列b和分配这些主ID 1,simillarly在具有id为1另一行具有对应列b = 2所以所有的搜索列b中的 2 并指定主ID.反之亦然.

我已经完成了以下代码,但它只进行了1次roatation:列a到列b,b到a

  masterCombine <- function(data, col1="a", col2="b", masterName="c"){

  skipList <- NULL

  masterId <- 1

  for( p in 1: nrow(data)){
    ind <- ind1 <- ind2 <- ind3 <- ind4 <- NULL
    if(!p %in% skipList){

      ind1 <- which(data[, col1] == data[, col1][p])
      for( ij in ind1){
        ind2 <-  which(data[ ,col2] == data[ ,col2][ij])
        for(j in ind2){
          ind3<- which(data[ , col1] == data[ ,col1][j])
          ind4 <- append(ind4, ind3)
        }

      }

      ind <- unique(append(ind1,ind4))
      skipList <- append(skipList, ind)
      data[ind, masterName] <- masterId

      masterId <-  masterId + 1
    }
  }

  return(data)
}
Run Code Online (Sandbox Code Playgroud)

我如何实现这种递归匹配?

the*_*ail 6

您可以使用igraph包及其clusters()功能执行类似的操作.您只需要确保首先a将列中的b值明确记录到列值中.

library(igraph)
data <- data.frame(a=c(1,1,2,2,3,3,4,5), b=c(1,2,2,3,3,4,5,6))
newdata <- mapply(paste0, names(data), data)
g <- graph.edgelist(newdata)
clusters(g)$membership
#a1 b1 b2 a2 b3 a3 b4 a4 b5 a5 b6 
# 1  1  1  1  1  1  1  2  2  3  3 

cg <- clusters(g)$membership
data$c <- cg[match(newdata[,"a"],names(V(g)))]

#  a b c
#1 1 1 1
#2 1 2 1
#3 2 2 1
#4 2 3 1
#5 3 3 1
#6 3 4 1
#7 4 5 2
#8 5 6 3
Run Code Online (Sandbox Code Playgroud)

对于视觉民谣,这里是图形表示 plot(g)

在此输入图像描述