2017-03-05 11 views
1

私はテキスト文字列を含むベクトルを持つデータフレームを持っています。私は、各文字列がいくつかのリストの1つに含まれているかどうかに基づいて、これらの文字列を値(0,1,2、...)に再コードし、データフレーム内の新しいベクトルに割り当てようとしていますR - 複数のリストの1つとの一致に基づいてベクトルに値を代入する

new_vector = (2, 1, 3, 3, 2) 

vector = c("A", "B", "C", "D", "E") 
list1 = c("B", "G", "P", "Z") 
list2 = c("A", "E", "M", "Q") 
list3 = everything not in list1 or list2 

新しいベクトルは、ベクトル[I]はLIST1、またはリスト2、又はLIST3に含まれているかどうかに応じて "0"、 "1"、または "2" を割り当てるべきです

私は%in%のさまざまな順列を試しましたが、問題は "ベクトル"が非常に長く(数十万の要素)、そして私が照合しているリストの中にはかなり長いものもあります(10-30要素)。私は動作する声明を持っていますが、エクストリームが遅いです。モスを見ているとゆっくりと成長する。

このような畳み込みマッチングシナリオを最適にスピードアップするためのR "トリック"は何ですか?

答えて

2

まず、あなたがいない番号の名前で、単一のオブジェクトに一緒にあなたのリストを格納する必要があります

L = list(list1, list2) 

を次に、あなたはかなり速いマッチングにdata.table使用することができます。

library(data.table) 
LDT = rbindlist(lapply(L, data.table), idcol = TRUE) 
vDT = data.table(v = vector) 

vDT[, id := LDT[vDT, on=.(V1 = v), .id]] 

# v id 
# 1: A 2 
# 2: B 1 
# 3: C NA 
# 4: D NA 
# 5: E 2 

あり「他のリストにないものすべて」のリストを作成する必要はありません。ここに示すように、NAに割り当てられるだけです。

あなたのリストが互いに素でない場合、これは奇妙な方法で解除されますので、その場合は、あなたが停止するようにルールを設定することもできます。

stopifnot(!anyDuplicated(LDT[, "V1"])) 

はそれがの仕組み

LDTとvDTはテーブルであり、結合の構文はx[i,on=,j]です。結合では、iを使用してxの行を検索します。 jは、一致する行(ここではiの列の1つ)を使用して計算された値です。

列を割り当てるには、colname := expressionのようなj引数を使用します。詳細については、the websiteを参照してください。

+1

OMG、それは信じられないほどうまく動作します!ありがとう、フランク - あなたは本当に私の隠しを救った! それは間違いなく私が個人的な図書館に入れている秘訣です。 – TPL

関連する問題