2014-01-27 5 views
2

У меня есть список матриц:Mean списка матриц по элементу

.list <- list(matrix(1:25, ncol = 5), matrix(11:35, ncol = 5)) 

Я хотел бы использовать метод Reduce найти элемент, от поэлементно с помощью матриц в списке.

Другими словами, я ищу следующий результат:

res = matrix(6:30, ncol = 5) 

Я попытался следующие:

res = Reduce(mean, .list) 

, но я получаю сообщение об ошибке:

Error in mean.default(init, x[[i]]) : 
    'trim' must be numeric of length one 

Обратите внимание, что элементом матрицы может быть NA. Любая помощь будет оценена! Спасибо!!

ответ

1

Это один из способов с mapply.

matrix(do.call(mapply, c(function(...) mean(unlist(list(...))), .list)), ncol=5) 

В качестве примечания, .list не самый лучший способ использовать ключевое слово в качестве имени переменной. В R префикс периода означает нечто вроде «мета-переменной», и эти переменные не будут отображаться при вызове ls(). Вы можете сделать list. или легче читать list_.

+0

Ну, ваш ответ велик, спасибо.Однако я нашел способ сделать это, используя «Уменьшить» (см. Мой собственный ответ). Кажется, это правильно, не так ли? – Mayou

+0

Да, да, +1. Извините меня, почему я ем свои слова ... –

4

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

Чтобы получить массив из .list, unlist его и поставить соответствующие размеры (которые могут быть автоматизированы путем поиска dim() из .list[[1]] и length(.list):

arr <- array(unlist(.list), dim = c(5,5,2)) 

Затем получают желаемый результат с помощью rowMeans() (! да, действительно)

rowMeans(arr, dim = 2) 

R> rowMeans(arr, dim = 2) 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 6 11 16 21 26 
[2,] 7 12 17 22 27 
[3,] 8 13 18 23 28 
[4,] 9 14 19 24 29 
[5,] 10 15 20 25 30 

na.rm аргумент обрабатывает NA случай тоже:

R> rowMeans(arr, dim = 2, na.rm = TRUE) 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 6 11 16 21 26 
[2,] 7 12 17 22 27 
[3,] 8 13 18 23 28 
[4,] 9 14 19 24 29 
[5,] 10 15 20 25 30 

Более медленный способ заключается в использовании apply(), который может быть более поучительным относительно того, что rowMeans() делает:

R> apply(arr, 1:2, mean, na.rm = TRUE) 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 6 11 16 21 26 
[2,] 7 12 17 22 27 
[3,] 8 13 18 23 28 
[4,] 9 14 19 24 29 
[5,] 10 15 20 25 30 

т.е. применяя среднюю функцию, группируя данные по строкам и столбцам размеров. Подумайте о массиве как о коробке, причем высота окна будет третьим измерением. Эта коробка состоит из маленьких кубов, таких как рубиновый куб. Мы хотим, чтобы среднее количество маленьких кубов было сложено над каждой комбинацией строк и столбцов; среднее количество маленьких кубов, уложенных выше (1,1) и т. д. Это то, что делают функции apply() и rowMeans(), если вы обрабатываете множество матриц в списке как массив.

+0

+1 это намного чище. –

+3

+1 Также имеет значение: '? Simplify2array'. – Arun

+0

@Arun Спасибо за указатель; Я полностью забыл об этом! –

6

Я просто понял, что это может быть достигнуто следующим образом (с помощью функции Reduce):

tmp = Reduce('+', .list) 
result = tmp/length(.list) 
+1

Я не думаю, что это будет объяснять 'NA', если в этом случае результат не будет« NA »? –

+0

Чтобы обработать 'NA', вам нужно применить функцию, которая сделала' '+ '()' после удаления элементов 'NA'. –

+0

Просто добавьте 'lapply (list_, function (x) x *! Is.na (x))' перед тем, как сделать 'Уменьшить (..)' возможно .. – Arun

Смежные вопросы