2016-12-15 9 views
1

имеет списки, первая (список1) имеет id, имя, возраст и другие (список2, list3, ..) имеет идентификаторы и тестовое значение (уникальное).Функция 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 

Я пытаюсь добавить LIST1 тестовое значение для каждого идентификатора (не каждый идентификатор имеет проверочное значение).

это часть кода:

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

, но вместо этого смотрит вверх тестовое значение по идентификатору, он копируется только первое тестовое значение из list2 и скопировать его на 200 клеток, а другой 3000 являются Н/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

merge не подходит для моих целей, я не хочу создавать другой файл и объединять два. Я просто хочу скопировать одно значение из каждого списка2, list3 .. в список1, который имеет тот же идентификатор. – anat

ответ

2

Сначала у вас есть опечатки в вашем примере. Во-вторых, для назначения «list1 $ test1value» должно быть добавлено «[i]», чтобы не сохранять за каждый раунд. Также не должно быть «[i]» добавлено к list2$id, так как вы хотите искать весь вектор для поиска.

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 будет автоматически перебирать каждый элемент по одному и искать его в другом векторе для вас. Он также будет упорядочивать результат в наборе данных.

Я закрою это как дубликат, потому что, как и другие, 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