Как преобразовать 4-мерный массив в 3-мерное подмножество массива на определенных элементах одного из измерений - PullRequest
1 голос
/ 15 января 2012

Это, вероятно, простой вопрос ... но я действительно изо всех сил, поэтому помощь очень ценится.

У меня есть данные 4d, которые я хочу преобразовать в данные 3D.Данные имеют следующие атрибуты:

lon <- 1:96  
lat <- 1:73  
lev <- 1:60  
tme <- 1:12

data <- array(runif(96*73*60*12), 
              dim=c(96,73,60,12) ) # fill with random test values  

Я хотел бы рассчитать среднее значение первых нескольких уровней (скажем, 1: 6).Новые данные будут иметь вид:

new.data <- array(96*73*12), dim=c(96,73,12) ) # again just test data  

, но будут содержать среднее из первых 5 уровней данных.На данный момент единственный способ, которым я смог заставить это работать, - написать довольно неэффективный цикл, который извлекает каждый из первых 5 уровней и делит сумму этих значений на 5, чтобы получить среднее значение.

Я пробовал:

new.data <- apply(data, c(1,2,4), mean)  

Что дает мне среднее значение ВСЕХ вертикальных уровней, но я не могу понять, как установить подмножество 3-го измерения, чтобы получить среднее значение только для нескольких!например,

new.data <- apply(data, c(1,2,3[1:5],4), mean) # which returns   
  Error in ds[-MARGIN] : only 0's may be mixed with negative subscripts

Я отчаянно нуждаюсь в помощи!

Ответы [ 2 ]

3 голосов
/ 15 января 2012

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

> str(apply(data[,,1:6,] , c(1,2,4), FUN=mean) )
 num [1:96, 1:73, 1:12] 0.327 0.717 0.611 0.388 0.47 ...

Этовозвращает матрицу 96 x 73 на 12.

0 голосов
/ 16 января 2012

В дополнение к ответу @DWin, я бы порекомендовал пакет plyr.Пакет предоставляет apply подобные функции.Анальг apply - это функция plyr aaply.Первые две буквы функции plyr указывают вход и тип вывода, aa в данном случае array и array.

> system.time(str(apply(data[,,1:6,], c(1,2,4), mean)))
 num [1:96, 1:73, 1:12] 0.389 0.157 0.437 0.703 0.61 ...
   user  system elapsed 
  2.180   0.004   2.184 
> Library(plyr)
> system.time(str(aaply(data[,,1:6,], c(1,2,4), mean)))
 num [1:96, 1:73, 1:12] 0.389 0.157 0.437 0.703 0.61 ...
 - attr(*, "dimnames")=List of 3
  ..$ X1: chr [1:96] "1" "2" "3" "4" ...
  ..$ X2: chr [1:73] "1" "2" "3" "4" ...
  ..$ X3: chr [1:12] "1" "2" "3" "4" ...
   user  system elapsed 
 40.243   0.016  40.262 

В этом примере это медленнее, чем apply, но есть несколько преимуществ.Пакет поддерживает параллельную обработку, он также поддерживает вывод результатов в data.frame или list (удобно для построения графиков с использованием ggplot2) и может отображать индикатор выполнения (хорошо для длительных процессов).Хотя в этом случае я все равно подам заявку из-за производительности.

Более подробную информацию о пакете plyr можно найти в этой статье .Может быть, кто-то может прокомментировать плохую производительность aaply в этом примере?

...