2016-12-15 5 views
1

のリストを持ち、最初のもの(list1)はid、name、ageを持ち、他のもの(list2、list3、..)はIDとテスト値(unique)を持ちます。MATCH関数がr

リスト1:

id age name bio-test  
1 40 danny 
2 16 nora    
3 35 james 
4 21 ben 

は、リスト2(バイオテスト):

id test passed year 
1 100 yes 1 
5 80 yes n/a  
4 55 no 2 

私は、各IDにテスト値をリスト1に追加しようとしています(すべてのidがテスト値を持っていません)。

これはコードの一部である:

for (i in 1:length(list1)) { 
list1$test1value <- list2$test[match(list1$id[i], list2$id[i]), 
nomatch = NA_integer_, incomparables = NULL)] } 

代わりIDによって試験値を探し、それがLIST2からちょうど最初のテスト値をコピーして、200個の細胞および他の3000にコピーがNであります/ A.

何が間違っていますか?

+0

を変更しました。ありがとうございました。 – anat

+0

ここから[関連する質問](http://stackoverflow.com/questions/41149718/overwriting-a-row-with-a-matched-id-value-in-the-same-dataframe/41150472#41150472)から昨日。私の答えは 'match'を使って欠損値の行を埋めています。あなたの問題は 'merge'で簡単に解決されます。 'merge(df1、df2、by =" id "、all = TRUE)のようなものです。 – lmo

+0

マージは私の目的には良くないので、別のファイルを作成して2つをマージする必要はありません。各リスト2から1つの値を複写したいのですが、同じIDを持つリスト1にコピーしたいだけです。 – anat

答えて

2

まず、あなたの例にタイプミスがあります。第2に、 'list1 $ test1value'の割り当てには、各ラウンドで保存しないために '[i]'が追加されていなければなりません。検索のためにベクトル全体を検索したいので、list2$idに '[i]'を追加する必要はありません。

for (i in 1:length(list1)) { 
    list1$test1value[i] <- list2$test[match(list1$id[i], list2$id, 
          nomatch = NA_integer_, incomparables = NULL)] } 

コードは機能しますが、ここでループする理由はありません。あなたはRがどのように動作するかについての理解の欠如を示しています。以下のコードはまったく同じことをはるかに速くします。

list1$test1value <- list2$test[match(list1$id, list2$id)] 

あなたはその手を保持し、どのようにベクトルの各要素を通過するように指示する必要がないようにRが構築されています。 matchが自動的に各メンバーを1つずつ繰り返して、それを他のベクターで探します。また、結果セットをデータセット内に規則的な方法で割り当てます。

他の人も示唆しているように、mergeがこれに最適ですので、これを複製として閉じます。

merge(list1, list2[c("id", "test")], all.x=TRUE) 
# id age name test 
#1 1 40 danny 100 
#2 2 16 nora NA 
#3 3 35 james NA 
#4 4 21 ben 55 
+0

ありがとうございます。 – anat