Сравнение векторов - PullRequest
       31

Сравнение векторов

1 голос
/ 18 мая 2011

Я новичок в R и пытаюсь найти лучшее решение для эффективного выполнения этой довольно простой задачи.

У меня есть data.frame M со 100,000 строками (и многие столбцы, из которых 2 столбца относятся к этой проблеме, я назову M1, M2). У меня есть еще один data.frame, где столбец V1 с около 10000 элементов имеет важное значение для этой задачи. Моя задача такова:

Для каждого элемента в V1 найдите, где он встречается в M2 и вытащите соответствующий M1. Я могу сделать это, используя цикл for, и это ужасно медленно! Я привык к Matlab и Perl, и это всегда в R! Конечно, есть лучший способ. Буду признателен за любые ценные предложения по выполнению этой задачи ...

for (x in c(1:length(V$V1)) {  
    start[x] = M$M1[M$M2 == V$V1[x]]  
}  

Существует только 1 элемент, который будет соответствовать, и поэтому я могу использовать логический оператор, чтобы напрямую получить элемент в начальном векторе. Как я могу векторизовать это?

Спасибо!

Ответы [ 3 ]

6 голосов
/ 18 мая 2011

Вот еще одно решение, использующее тот же пример @ aix.

M[match(V$V1, M$M2),]

Для оценки производительности мы можем использовать пакет R rbenchmark.

library(rbenchmark)
f_ramnath = function() M[match(V$V1, M$M2),]
f_aix = function() merge(V, M, by.x='V1', by.y='M2', sort=F)
f_chase = function() M[M$M2 %in% V$V1,] # modified to return full data frame

benchmark(f_ramnath(), f_aix(), f_chase(), replications = 10000)
     test replications elapsed relative
2     f_aix()        10000  12.907 7.068456
3   f_chase()        10000   2.010 1.100767
1 f_ramnath()        10000   1.826 1.000000
4 голосов
/ 18 мая 2011

Другой вариант - использовать оператор %in%:

> set.seed(1)
> M <- data.frame(M1 = sample(1:20, 15, FALSE), M2 = sample(1:20, 15, FALSE))
> V <- data.frame(V1 = sample(1:20, 10, FALSE))
> M$M1[M$M2 %in% V$V1]
[1]  6  8 11  9 19  1  3  5
2 голосов
/ 18 мая 2011

Похоже, вы ищете merge:

> M <- data.frame(M1=c(1,2,3,4,10,3,15), M2=c(15,6,7,8,-1,12,5))
> V <- data.frame(V1=c(-1,12,5,7))
> merge(V, M, by.x='V1', by.y='M2', sort=F)
  V1 M1
1 -1 10
2 12  3
3  5 15
4  7  3

Если V$V1 может содержать значения, отсутствующие в M$M2, вы можете указать all.x=T. Это заполнит пропущенные значения символами NA вместо того, чтобы исключать их из результата.

...