2017-01-08 10 views
4

ここsetdiff正常な動作です:R:setdiffの貪欲でないバージョン?

x <- rep(letters[1:4], 2) 
x 
# [1] "a" "b" "c" "d" "a" "b" "c" "d" 

y <- letters[1:2] 
y 
# [1] "a" "b" 

setdiff(x, y) 
# [1] "c" "d" 

...しかし、私はy一度だけを取り出し、そのため次のような結果を得ることがしたい場合は?

# "c" "d" "a" "b" "c" "d"

私はsetdiffまたは%in%のいずれかを使用して簡単な解決策があることを推測しているが、私はそれを見ることはできません。

+0

に存在する同一の要素の数を取る[seq_len(myCounts[i])]から来ています過剰な私はそこにはもっと簡単な解決策があることを望んでいます、そして、私は明らかに欠けているだけです。 –

+0

一般的には、次回は、試したことを含めると良いです(「今のようなことをしています_」)。それはあなたが自分自身を助けるために時間を割いたことを実証し、明らかな答えを繰り返すことから私たちを救います。乾杯。 – Henrik

+0

@Henrikフィードバックをありがとう。私はあなたがお勧めするようにしていただろうが、残念ながら、ここには何も置いておらず、欲張りな解決策しか見つけられていない。 –

答えて

5

matchは、その最初の引数の(最初の)一致の位置のベクトルを2番目に返します。これは、インデックスのコンストラクタとして使われています:

が「Y」で重複していると、あなたがそこにその数に比例して削除をしたい場合は、私の心に来た最初の事はforループで
x[ -match(y,x) ] 
#[1] "c" "d" "a" "b" "c" "d" 

y <- c("a","b","a") 
x2 <- x 
for(i in seq_along(y)){ x2 <- x2[-match(y[i],x2)] } 

> x2 
[1] "c" "d" "b" "c" "d" 

これは、以下に示す表の手法を使用した場合の1つの可能性があります。いくつかの "set"関数を使用しますが、実際には設定された問題ではありません。もう少し "ベクトル化された"と思われます。

c(table(x [x %in% intersect(x,y)]) - table(y[y %in% intersect(x,y)]) , 
    table(x[!x %in% intersect(x,y)])) 
a b c d 
0 1 2 2 
+0

「y」に重複があるとループする以外の方法はないと私は驚きますが、うまくいくはずです。 –

+1

まあ、奇妙なことだと思います。動機付けのユースケースはありません。これを行うためのあらかじめ作られた機能の必要性についてのより良い説明がなければ、あなたの「驚き」は少し予期しているように見えます。 –

+0

ここに平和と愛のOPがあります。ここにユースケースがあります:(1)私は要素のベクトルを持っており、そこから別のベクトルを "減算"する必要があります。 (2)両方のベクトルがチャタリングである。 (3)両方のベクトルに重複があるかもしれない。 ---これは非常に頻繁な使用例ではないかもしれませんが、実際は減算/除去操作です。 –

0

ここでは別のループ方法があります。私は42の方法がよりクリーンだと思うが、それは別の選択肢を提供する。

# construct a table containing counts for all possible values in x and y in y 
myCounts <- table(factor(y, levels=sort(union(x, y)))) 

# extract these elements from x 
x[-unlist(lapply(names(myCounts), 
       function(i) which(i == x)[seq_len(myCounts[i])]))] 

「非貪欲」の側面は、唯一の私は今少しそのような何かをやっている、しかし、はい、それはちょっとだY