我创建了一个数据框
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)
我如何实现这种递归匹配?
您可以使用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)