Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 确定链接在一起的多组关联事件_R_Grouping_Identifier_Linkage - Fatal编程技术网

R 确定链接在一起的多组关联事件

R 确定链接在一起的多组关联事件,r,grouping,identifier,linkage,R,Grouping,Identifier,Linkage,以链接ID的简单数据框为例: test <- data.frame(id1=c(10,10,1,1,24,8),id2=c(1,36,24,45,300,11)) > test id1 id2 1 10 1 2 10 36 3 1 24 4 1 45 5 24 300 6 8 11 现在我大致知道了我想要的逻辑,但不知道如何优雅地实现它。我正在考虑在%中递归使用match或%in%来遍历每个分支,但这次我真的被难倒了 我要追求的最终结果是: re

以链接ID的简单数据框为例:

test <- data.frame(id1=c(10,10,1,1,24,8),id2=c(1,36,24,45,300,11))

> test
  id1 id2
1  10   1
2  10  36
3   1  24
4   1  45
5  24 300
6   8  11
现在我大致知道了我想要的逻辑,但不知道如何优雅地实现它。我正在考虑在%中递归使用
match
%in%
来遍历每个分支,但这次我真的被难倒了

我要追求的最终结果是:

result <- data.frame(group=c(1,1,1,1,1,1,2,2),id=c(10,1,24,36,45,300,8,11))

> result
  group  id
1     1  10
2     1   1
3     1  24
4     1  36
5     1  45
6     1 300
7     2   8
8     2  11
结果
组id
1     1  10
2     1   1
3     1  24
4     1  36
5     1  45
6     1 300
7     2   8
8     2  11

Bioconductor包RBGL(BOOST图形库的R接口)包含 一个函数,
connectedComp()
,用于标识图形中连接的组件-- 正是你想要的

(要使用该功能,您首先需要安装可用和可用的graphRBGL软件包。)

库(RBGL)

测试这里有一个替代答案,是我在Josh向正确方向轻推后发现的。此答案使用
igraph
软件包。 对于那些正在搜索并找到这个答案的人,我的
测试
数据集在图论中被称为“边列表”或“邻接列表”()

库(igraph)

不使用包装进行测试:

# 2 sets of test data
mytest <- data.frame(id1=c(10,10,3,1,1,24,8,11,32,11,45),id2=c(1,36,50,24,45,300,11,8,32,12,49))
test <- data.frame(id1=c(10,10,1,1,24,8),id2=c(1,36,24,45,300,11))

grouppairs <- function(df){

  # from wide to long format; assumes df is 2 columns of related id's
  test <- data.frame(group = 1:nrow(df),val = unlist(df))

  # keep moving to next pair until all same values have same group
  i <- 0
  while(any(duplicated(unique(test)$val))){
    i <- i+1

    # get group of matching values
    matches <- test[test$val == test$val[i],'group']

    # change all groups with matching values to same group
    test[test$group %in% matches,'group'] <- test$group[i]
  }

  # renumber starting from 1 and show only unique values in group order
  test$group <- match(test$group, sort(unique(test$group)))
  unique(test)[order(unique(test)$group), ]
}

# test
grouppairs(test)
grouppairs(mytest)
#2组测试数据

我的测试你说的是递归。。。我想我在做的时候会非常简洁

测试数据

mytest <- data.frame(id1=c(10,10,3,1,1,24,8,11,32,11,45),id2=c(1,36,50,24,45,300,11,8,32,12,49))
test <- data.frame(id1=c(10,10,1,1,24,8),id2=c(1,36,24,45,300,11))
aveminrec()可能与您的想法一致,不过我敢打赌,有一种方法可以更直接地遍历每个分支,而不是重复ave(),它本质上是split()和lappy()。也许是递归拆分和重叠?实际上,它就像重复的部分分支,或者交替地稍微简化2个向量,而不丢失组信息


也许其中的一部分可以用于解决实际问题,但groupvalues()太密集了,至少在没有注释的情况下无法阅读。我还没有检查性能与使用ave的for循环以及以这种方式翻转组相比如何。

谢谢您的回答。在搜索更多信息时,我现在还可以使用“连接组件”一词。很高兴能够为您指出一条有用的途径。干杯祝你快乐。我刚刚测试了这个答案,链接和包确实成功了,就像九年前一样。我希望如此,而这个问题在25年前,当我和SAS试图解决这个问题时,我的头撞在墙上。@bondeddust-巧合的是,这个问题是由于试图替换一个丑陋的还有一段低效的SAS代码做了类似的事情。现在我忘记了这个问题和答案,但最近的邮件@HenrikHi@提醒我了!我认为
graph.data.frame
graph\u from\u data\u frame
取代,而
clusters
组件组成。至少当我
使用这些函数时,我会被重定向到这些函数。类似的欢呼声R中有一个名为
Recall
的函数,据说它改进了基于递归的代码。而
ave
可以被认为是
lapply
split
的简单捆绑,但它实际上不能处理分组中多个列的操作。
library(igraph)
test <- data.frame(id1=c(10,10,1,1,24,8 ),id2=c(1,36,24,45,300,11))
gr.test <- graph_from_data_frame(test)
links <- data.frame(id=unique(unlist(test)),group=components(gr.test)$membership)
links[order(links$group),]

#   id group
#1  10     1
#2   1     1
#3  24     1
#5  36     1
#6  45     1
#7 300     1
#4   8     2
#8  11     2
# 2 sets of test data
mytest <- data.frame(id1=c(10,10,3,1,1,24,8,11,32,11,45),id2=c(1,36,50,24,45,300,11,8,32,12,49))
test <- data.frame(id1=c(10,10,1,1,24,8),id2=c(1,36,24,45,300,11))

grouppairs <- function(df){

  # from wide to long format; assumes df is 2 columns of related id's
  test <- data.frame(group = 1:nrow(df),val = unlist(df))

  # keep moving to next pair until all same values have same group
  i <- 0
  while(any(duplicated(unique(test)$val))){
    i <- i+1

    # get group of matching values
    matches <- test[test$val == test$val[i],'group']

    # change all groups with matching values to same group
    test[test$group %in% matches,'group'] <- test$group[i]
  }

  # renumber starting from 1 and show only unique values in group order
  test$group <- match(test$group, sort(unique(test$group)))
  unique(test)[order(unique(test)$group), ]
}

# test
grouppairs(test)
grouppairs(mytest)
mytest <- data.frame(id1=c(10,10,3,1,1,24,8,11,32,11,45),id2=c(1,36,50,24,45,300,11,8,32,12,49))
test <- data.frame(id1=c(10,10,1,1,24,8),id2=c(1,36,24,45,300,11))
aveminrec <- function(v1,v2){
  v2 <- ave(v1,by = v2,FUN = min)
  if(identical(v1,v2)){
    as.numeric(as.factor(v2))
  }else{
    aveminrec(v2,v1)
  }
}
groupvalues <- function(valuepairs){
  val <- unlist(valuepairs)
  grp <- aveminrec(val,1:nrow(valuepairs))
  unique(data.frame(grp,val)[order(grp,val), ])
}
groupvalues(test)
groupvalues(mytest)