2016-03-23 21 views
8

İki dizgim var, a <- "AERRRTX"; b <- "TRRA".Iki dizeleri arasındaki ayrım farklı karakterleri ayıkla

ben setdiff kullanır Extract characters that differ between two strings yanıtını, denedik

, b kullanılmayan yani "ERX" a karakterleri ayıklamak istiyorum. b "R" ve setdiff, a içinde üç "R" s tüm ortadan kaldıracak çünkü "EX" döndürür. Amacım her karakteri ayrı olarak ele almak, böylece a'daki üç R'nin sadece ikisi ortadan kaldırılmalıdır.

setdiff yerine neler kullanabileceğime dair herhangi bir öneri veya çıktımı elde etmek için başka bir yaklaşım mı arıyorsunuz?

cevap

10

farklı bir yaklaşım pmatch kullanarak,

a1 <- unlist(strsplit(a, "")) 
b1 <- unlist(strsplit(b, "")) 

a1[!1:length(a1) %in% pmatch(b1, a1)] 

#[1] "E" "R" "X" 

başka örnek,

a <- "Ronak";b<-"Shah" 

a1 <- unlist(strsplit(a, "")) 
b1 <- unlist(strsplit(b, "")) 
a1[!1:length(a1) %in% pmatch(b1, a1)] 

# [1] "R" "o" "n" "k" 
+1

Minör noktası: Bu tavsiye edilir Yaygın olarak kullanılan yerleşik bir işlev olduğundan, 'c' atanmasını engellemek için. Eğer 'c' herhangi bir çevreleyen ortamda tanımlanmış bir değişken ise, bu tanımlayıcıya yapılan başvurular ona bağlanarak çok fazla kod çözebilir. Örneğin, 'do.call (c, ...) 'bu durumda başarısız olur. – bgoldst

+0

@bgoldst haklısınız. Güncellenmiş. Teşekkürler! –

+2

Güzel bir alternatif. Üçüncü hattınızı 'a1 [-pmatch (b1, a1)]' ile değiştirebilirsiniz. Ayrıca, davranışını "eşleştirmeye" ayıran "pmatch" in "duplicates.ok = FALSE" argümanını not etmek yararlı olacaktır. –

4

Biz gittikçe b bulundu a her karakterin dan ortadan kaldırmak için Reduce() kullanabilirsiniz:

a <- 'AERRRTX'; b <- 'TRRA'; 
paste(collapse='',Reduce(function(as,bc) as[-match(bc,as,nomatch=length(as)+1L)],strsplit(b,'')[[1L]],strsplit(a,'')[[1L]])); 
## [1] "ERX" 

Bu a içinde hayatta kalan karakterlerin sırasını koruyacak.


başka bir yaklaşım, a oluşumuyla ilgili indeksi her bir karakteri işaretlemek b için aynı şeyi etmektir ve o zaman setdiff() kullanabilirsiniz: grubuna fonksiyonu vsetdiff kullanabilirsiniz

a <- 'AERRRTX'; b <- 'TRRA'; 
pasteOccurrence <- function(x) ave(x,x,FUN=function(x) paste0(x,seq_along(x))); 
paste(collapse='',substr(setdiff(pasteOccurrence(strsplit(a,'')[[1L]]),pasteOccurrence(strsplit(b,'')[[1L]])),1L,1L)); 
## [1] "ERX" 
4

vecsets paket

install.packages("vecsets") 
library(vecsets) 
a <- "AERRRTX" 
b <- "TRRA" 
Reduce(vsetdiff, strsplit(c(a, b), split = "")) 
## [1] "E" "R" "X" 
3

data.table package` kullanarak alternatif:

library(data.table) 

x = data.table(table(strsplit(a, '')[[1]])) 
y = data.table(table(strsplit(b, '')[[1]])) 

dt = y[x, on='V1'][,N:=ifelse(is.na(N),0,N)][N!=i.N,res:=i.N-N][res>0] 

rep(dt$V1, dt$res) 
#[1] "E" "R" "X" 
+0

Çok iyi, + 1.᠎ – bgoldst

İlgili konular