R中的递归分组

时间:2017-02-13 19:09:26

标签: r dplyr

我正在尝试找到一种基于"重叠"创建顺序Group_ID的方法。变量。我描述这个的最简单方法是使用房屋,贷款和借款人的例子。

假设我们有以下示例

df <- data.frame(house     = c('H_01','H_02','H_03','H_04','H_05'),
                 loan      = c('L_01','L_02','L_02','L_03','L_04'),
                 borrower  = c('B_01','B_01','B_02','B_03','B_04'))

假设所有变量(房屋,贷款,借款人)之间存在多对多的关系 因此,例如,房屋1(H_01)与贷款1(L_01)和借款人1(B_01)相关联。但B_01也与L_02相关联,H_02本身与H_03相关联,但也链接到G_01 - 因此我的表格中的前3行应标记为{{1} (对于第1组)。

H_04与不属于任何其他记录的L_03相关联,B_03也与任何其他记录无关,因此第四条记录应位于G_02 {1}}。通过模拟探索,我们应该看到记录5属于它自己的子组G_03

有没有办法优雅dplyr(最好但不一定)实现G_01G_02G_03的分组?

2 个答案:

答案 0 :(得分:4)

您正在寻找“连接组件”。我们可以首先重新排列数据(melt),然后让一个实施良好的图形库(igraph)来完成工作,从而将关系视为图形。

library(reshape2)
library(igraph)

components(graph.data.frame(melt(df,id="house")[,c(1,3)]))$membership[df$house]

  # H_01 H_02 H_03 H_04 H_05 
  #  1    1    1    2    3 

为了概括,您可能希望将与值的关系粘贴在一起以“颜色”节点,例如,

with(melt(df,id="house"),data.frame(x=house,y=paste(variable,value,sep=".")))

在创建图表之前。

答案 1 :(得分:1)

一个。 Webb的解决方案显然更胜一筹。但是自从我制定了 解决方案之后,我会把它放在这里。

df = data.frame(apply(df, 2, as.character), stringsAsFactors = FALSE)
g = 1
df$group[1] = paste("G",g,sep = "")

#Find out unique groups and assign "CHECK" to rows in same groups
for (i in 2:nrow(df)){
    if (any(df[i,1:3] %in% unlist(df[1:(i-1),1:3]))){
        df$group[i] = "CHECK"
    } else {
        g = g + 1
        df$group[i] = paste("G",g,sep = "")
    }   
}

#Assign groups to rows in same group
for (i in 1:nrow(df)){
    if (df$group[i] != "CHECK"){
        next
    }
    if (df$house[i] %in% df$house[1:i]){
        df$group[i] = df$group[match(df$house[i], df$house[1:i])]        
    }
    if (df$loan[i] %in% df$loan[1:i]){
        df$group[i] = df$group[match(df$loan[i], df$loan[1:i])]        
    }
    if (df$borrower[i] %in% df$borrower[1:i]){
        df$group[i] = df$group[match(df$borrower[i], df$borrower[1:i])]       
    }
}

#> df$group
#[1] "G1" "G1" "G1" "G2" "G3"