2017-03-06 25 views
1

我有一个这样的字符串:基于R比较字符串中的子元素......和总结它,以便有没有重复的子元素

data <- c("A:B:C", "A:B", "E:F:G", "H:I:J", "B:C:D") 

我想这个转换成字符串的:

c("A:B:C:D", "E:F:G", "H:I:J") 

的想法是,在字符串内的每个元素是子元素的另一个字符串(例如A,B,C)已被粘贴在一起(用Sep =“:”)。将字符串中的每个元素与所有其他元素进行比较以查找公共子元素,并将具有公共子元素的元素进行组合。

我不关心字符串(或子元素的顺序)FWIW的顺序。

感谢您提供的任何帮助!

-

到目前为止的答案...

我喜欢分贝的建议 - 并非最不重要的,因为它在基地R.呆然而,在一个更复杂的大集,它不是完美工作,直到一切再次运行。对于更复杂的数据集,可能需要重新运行两次以上的数据。

我对于电邮的建议有更多的困难。我不得不升级R来使用长度,然后我必须弄清楚如何到达终点,因为答案是不完整的。无论如何,这就是我如何走到最后(我怀疑有更好的方法)。这与一个更大的集合工作没有困难。

library(igraph) 
spl <- strsplit(data,":") 
combspl <- data.frame(
    grp = rep(seq_along(spl),lengths(spl)), 
    val = unlist(spl) 
) 
cl <- clusters(graph.data.frame(combspl))$membership[-(1:length(spl))] 

dat <- data.frame(cl) # after getting nowhere working with the list as formatted 
dat[,2] <- row.names(dat) 
a <- character(0) 
for (i in 1:max(cl)) { 
    a[i] <- paste(paste0(dat[(dat[,1] == i),][,2]), collapse=":") 
} 

a 
#[1] "A:B:C:D" "E:F:G" "H:I:J" 

我现在要离开这里了。

+0

你可以简化代码来获得你的确切结果,比如:sapply(split(names(cl),cl),paste,collapse =“;”)'。 – thelatemail

+0

'@ thelatemail'。当然,这似乎也有效。你介意添加这个额外的排序位,我最终使用到你的建议? - 在循环部分,我使用了'a [i] < - paste(paste0(sort(dat [(dat [,1] == i,] [,2],collapse =“:”)'另外,对于无论它是值得的,整个事物就是一个大循环的一部分(n = 1005),后面跟着一个

回答

2
a = character(0) 
for (i in 1:length(data)){ 
    a[i] = paste(unique(unlist(strsplit(data[sapply(1:length(data), function(j) 
     any(unlist(strsplit(data[i],":")) %in% unlist(strsplit(data[j],":"))))],":"))), collapse = ":") 
} 
unique(a) 
#[1] "A:B:C:D" "E:F:G" "H:I:J" 
+0

非常感谢,大部分似乎都适用,但我必须注意到当我试图大规模地使用这个脚本时,它在1%的案例中没有正确压缩一切(1005中的9个) - 压缩是不完整的。通过重复脚本,剩下的〜1%也被解决了。我不确定是什么导致了呃逆。 –

3

igraph库一种可能的应用,如果你认为你的价值观作为配对组的EdgeList都:

library(igraph) 
spl <- strsplit(data,":") 
combspl <- data.frame(
    grp = rep(seq_along(spl),lengths(spl)), 
    val = unlist(spl) 
) 
cl <- clusters(graph.data.frame(combspl))$membership[-(1:length(spl))] 
#A B C E F G H I J D 
#1 1 1 2 2 2 3 3 3 1 

split(names(cl),cl) 
#$`1` 
#[1] "A" "B" "C" "D" 
# 
#$`2` 
#[1] "E" "F" "G" 
# 
#$`3` 
#[1] "H" "I" "J" 

或者像折叠文本:

sapply(split(names(cl),cl), paste, collapse=";") 
#  1   2   3 
#"A;B;C;D" "E;F;G" "H;I;J"