2012-01-15 1 views
1

Вот, наверное, простой вопрос .. но я действительно борется, поэтому помощь очень ценится.Как преобразовать 4-мерный массив в подмножество 3d-массива по определенным элементам одного из размеров

У меня есть 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 

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

ответ

3

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 х 73 на 12 матриц.

+0

Спасибо за ответ! Я, хотя это было бы просто, но я думаю, что я немного смутился !! –

+0

Если бы это действительно ответили на вопрос, вы бы сделали другим читателям услугу, нажав на галочку. (На данный момент я действительно не нуждаюсь в дополнительных очках, но это будет отображаться как «неотвеченный вопрос», пока вы не будете использовать чек.) –

0

В дополнение к ответу @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 можно найти в this paper. Может быть, кто-то может прокомментировать плохую работу aaply в этом примере?

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

  • Нет связанных вопросов^_^