сопоставление разных столбцов нескольких данных

У меня есть функция, которая принимает два вектора и вычисляет числовое значение (например, corcorrelation). Однако у меня есть два набора данных примерно с 6000 столбцами (два набора данных имеют одинаковые размеры), где функция должна возвращать один вектор со значениями корреляции.

Код с циклом будет выглядеть так:

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])
}

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

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

> ReturnData
[1]  0.1247039 -0.9641188  0.5081204

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

Решение, данное @akrun, заключалось в использовании фреймов данных вместо матриц.

Кроме того, тест скорости между двумя предложенными решениями показал, что mapply-версия быстрее, чем 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

person David    schedule 24.10.2014    source источник


Ответы (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
person akrun    schedule 24.10.2014
comment
Спасибо, акрун. data.frame() был решением. - person David; 24.10.2014
comment
Я провел тест для двух разных версий. mapply кажется намного быстрее ... require(rbenchmark) set.seed(123) m=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="elapsed", replications=2) Возвращает истекшее время 0,1 для mapply и 0,14 для sapply. - person David; 24.10.2014
comment
@David Спасибо, что поделились тестами. Вы можете обновить это в своем сообщении. - person akrun; 24.10.2014