2014-10-24 4 views
0

У меня есть функция, которая принимает два вектора и вычисляет числовое значение (например, cor). Однако у меня есть два набора данных с примерно 6000 столбцами (два набора данных имеют одинаковые размеры), где функция должна возвращать один вектор со значениями корреляции.mapply over different columns of multiple data

код с петлей будет выглядеть следующим образом:

set.seed(123) 
m=matrix(rnorm(9),ncol=3) 
n=matrix(rnorm(9,10),ncol=3) 

colNumber=dim(m)[2] 
ReturnData=rep(NA,colNumber) 

for (i in 1:colNumber){ 
    ReturnData[i]=cor(m[,i],n[,i]) 
} 

Это прекрасно работает, но по соображениям эффективности я хочу использовать семью применять-, очевидно, функцию mapply.

Однако mapply(cor,m,n) возвращает вектор с длиной 9 NA с, где она должна возвращать:

> ReturnData 
[1] 0.1247039 -0.9641188 0.5081204 

РЕДАКТИРОВАТЬ/РЕШЕНИЕ

Решение как дано @akrun было использование dataframes вместо матриц.

Кроме того, тест скорости между двумя предлагаемых решений показал, что mapply -version быстрее, чем sapply:

require(rbenchmark) 
set.seed(123) 
#initiate the two dataframes for the comparison 
m=data.frame(matrix(rnorm(10^6),ncol=100)) 
n=data.frame(matrix(rnorm(10^6),ncol=100)) 
#indx is needed for the sapply function to get the column numbers 
indx=seq_len(ncol(m)) 
benchmark(s1=mapply(cor, m,n), s2=sapply(indx, function(i) cor(m[,i], n[,i])), order="elapsed", replications=100) 

#test replications elapsed relative user.self sys.self user.child sys.child 
#2 s2   100 4.16 1.000  4.15  0   NA  NA 
#1 s1   100 4.33 1.041  4.32  0   NA  NA 

ответ

1

Потому что ваш набор данных matrix, то mapply будет цикл по каждому элементу вместо каждого столбца , Чтобы этого избежать, конвертируйте в dataframe. Я не уверен, насколько это эффективно для больших наборов данных.

mapply(cor, as.data.frame(m), as.data.frame(n)) 
#  V1   V2   V3 
#0.1247039 -0.9641188 0.5081204 

Другой вариант заключается в использовании sapply без преобразования в data.frame

indx <- seq_len(ncol(m)) 
sapply(indx, function(i) cor(m[,i], n[,i])) 
#[1] 0.1247039 -0.9641188 0.5081204 
+0

Благодаря akrun. Решение 'data.frame()' было решением. – David

+0

@David Нет проблем. – akrun

+0

Я запустил Benchmark над двумя разными версиями. 'Mapply', кажется, намного быстрее ... ' требуют (rbenchmark) set.seed (123) м = data.frame (v1 = RNorm (10^6), v2 = RNorm (10^6), v3 = rnorm (10^6)) n = data.frame (v1 = rnorm (10^6), v2 = rnorm (10^6), v3 = rnorm (10^6)) indx = seq_len (ncol (m)) benchmark (s1 <- mapply (cor, m, n), s2 <- sapply (indx, function (i) cor (m [, i], n [, i])), order = " прошедшее ", replications = 2)' Возвращает истекшее время 0.1 для mapply и 0.14 для sapply. – David