2017-03-06 56 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"