2015-09-17 5 views
1

В R, у меня есть две матрицы, х и у, которые оба имеют одинаковое число столбцов, скажем, к примеру:Эффективного R сравнения матрицы

x <- matrix(runif(10*20),10,20) 
y <- matrix(runif(50*20),50,20) 

Что такое наиболее эффективного способ создания матрицу, содержащую результат следующего сравнения. Сравните каждую строку в x с каждой строкой в ​​y (сравнение строк 10x50), верните, сколько чисел в строке y меньше, чем соответствующее число в строке x. Поместите результаты в матрицу результатов 10x50.

Следующий код работает, но это не является эффективным:

result <- matrix(NA,10,50)  
for (i in 1:10) { 
     for (j in 1:50) { 
     result[i,j]<- sum(x[i,]>y[j,]) 
     } 
    } 
+0

Можете ли вы сделать ваш [? Пример воспроизводимая] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible -пример). Код, который вы предоставили, не запускается. – Heroka

+0

, и вы хотели сказать «вернуть, сколько чисел в строке« x »меньше соответствующего номера в строке« y », правильно? –

+0

Откуда вы знаете, что это не эффективно? с чем вы сравнили это? – pcantalupo

ответ

3

Действительно ваш код не работает, но я думаю, что вы имеете в виду y <- matrix(runif(50*20),50,20), правильно?

В этом случае вы можете использовать функцию outer:

outer(rowSums(x), rowSums(y), function(x, y) x > y) 

EDIT

Я понимаю, что вы имеете в виду, извините, могли бы получить, что также с ошибкой. Я думаю, что это собирается ускорить работу значительно задачу:

result2 <- rowSums(x[rep(1:nrow(x), nrow(y)), ] > 
    y[rep(1:nrow(y), each = nrow(x)), ]) %>% 
    matrix(nrow = nrow(x)) 
+0

Я действительно имел в виду, что, извините, вопрос был отредактирован, и теперь код работает. Ваш ответ возвращает booleans, хотя my возвращает целое число с числом вхождений x> y –

1

я думаю y <- matrix(runif(50)) и вы можете попробовать использовать один цикл, чтобы ускорить вычисление:

t(apply(y,1,function(u) rowSums(x<u))) 
0

Этот ответ основан на @ Ответ полковника Беавеля. Чтобы ускорить вычисление, вы можете использовать один цикл вместо двух и перебирать меньшую матрицу (в вашем примере x).

t(apply(x, 1, function(u)colSums(u > t(y)))) 

Еще одно важное замечание - факт u < t(y). R сравнивает матрицы по столбцам, поэтому важно сначала транспонировать y.

Полный пример с бенчмаркинга:

set.seed(1) 
x <- matrix(runif(10*20),10,20) 
y <- matrix(runif(50*20),50,20) 

f0 <- function(x, y) { 
result <- matrix(NA,10,50) 
for (i in 1:10) { 
     for (j in 1:50) { 
     result[i,j]<- sum(x[i,]>y[j,]) 
     } 
    } 
result 
} 

f1 <- function(x, y)t(apply(x,1,function(u)colSums(u>t(y)))) 

all.equal(f0(x, y), f1(x, y)) 
# [1] TRUE 

benchmark(f0(x, y), f1(x, y), order="relative") 
#  test replications elapsed relative user.self sys.self user.child sys.child 
# 2 f1(x, y)   100 0.035 1.000  0.032 0.004   0   0 
# 1 f0(x, y)   100 0.253 7.229  0.252 0.000   0   0 
Смежные вопросы