2016-03-23 20 views
8

私は2つの文字列、a <- "AERRRTX"; b <- "TRRA"を持っています。2つの文字列で異なる別の文字を抽出します

私は bで使用されていない aの文字を抽出したい

、すなわち「ERX」

私はsetdiffを使用していますExtract characters that differ between two stringsで答えを、試してみました。 bは "R"を持ち、setdiffaの3つの "R"をすべて削除するため "EX"を返します。私の目的は、各文字を区別できるように扱うことです。したがって、aの3つのRのうち2つだけを削除する必要があります。

setdiffの代わりに、私の出力を達成するために何ができるかについてのご意見はありますか?

答えて

10

pmatch

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

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

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

別の例として、

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

マイナーポイントを使用して異なるアプローチ:それはお勧めですが'c'の割り当てを避けるために、一般的に使われる組み込み関数です。 'c'が囲む環境で定義された変数である場合、その識別子への参照はそれに束縛され、多くのコードを混乱させる可能性があります。例えば、 'do.call(c、...)'はこの場合失敗します。 – bgoldst

+0

@bgoldstあなたは正しいです。更新しました。ありがとう! –

+2

良い選択肢。 3行目を 'a1 [-pmatch(b1、a1)]'に置き換えることができます。また、 'pmatch'の" duplicates.ok = FALSE "引数の動作を' match 'と区別するのに役立つでしょう –

4

私たちは、次々aからbで見つかった各文字を排除するためにReduce()を使用することができます。

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" 

これはaで生き残った文字の順序を維持します。


別のアプローチは、aにその発生率とのそれぞれの文字をマークbのための同じをすることであり、我々はsetdiff()使用することができます:あなたがから機能vsetdiffを使用することができます

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パッケージ

3

data.table package`使用する代替:

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

非常に良い、+1.᠎ – bgoldst

関連する問題