2013-05-17 5 views
1

Есть ли способ изящно указать срез в многомерном массиве в R, из-за чего количество измерений неизвестно заранее?r массив-срез программно определенного размера

Например, для 5-мерного массива, нарезка из последнего измерения может быть сделано с помощью

fourdimslice <- fivedimarray[,,,,1] 

но I'l нравится кодировать это для произвольных размеров, что-то вроде

slice <- arbitrarydimarray(dim=5, index=1) 

Я не мог понять, будет ли подход do.call('[', ...). Я также пробовал именованные измерения, но a[fifth=1] не интерпретируется так, как хотелось бы здесь.

Я полагаю, что функции, подобные apply(), необходимо выполнять аналогичные вещи.

+2

Смотрите, если http://stackoverflow.com/questions/14500707/select-along-one -of-n-dimensions-in-array/14501461 # 14501461 отвечает на ваш вопрос. – flodel

+0

Я на самом деле написал код однажды (когда был молод и глуп :-)), который посмотрел на количество измерений массива и построил строку, зациклив на что-то вроде 'foo <- 'x ['; для (i в 1: (n-1)) foo <- paste (foo, ',') '. Ответ В. Зоункинда очень приятный. –

ответ

5

Вы можете использовать asub, из пакета abind.

# Sample data: a 5-dimensional array 
x <- array(seq_len(prod(2:6)), dim=2:6) 

library(abind) 
str(asub(x, 1, 5)) 
# int [1:2, 1:3, 1:4, 1:5] 1 2 3 4 5 6 7 8 9 10 ... 
str(x[,,,,1]) 
# int [1:2, 1:3, 1:4, 1:5] 1 2 3 4 5 6 7 8 9 10 ... 
all(asub(x, 1, 5) == x[,,,,1]) 
# [1] TRUE 
0

Вот странное решение для извлечения первого слайса

your.array=array(runif(27),dim=c(3,3,3)) # this is to create an example of array from which you want a slice. 

array(your.array[1:prod(dim(your.array)[-1])],dim(your.array)[-1]) 
1

Если вы не хотите использовать abind пакет, он выглядит, как вы можете использовать два лайнера, основанный на slice.index. Я не знаю, что более эффективно ...

x <- array(seq_len(prod(2:6)), dim=2:6) 
library(abind) 
str(y <- asub(x, 1, 5)) 

Или:

z <- x[slice.index(x,5)==1] 

Это извлекает нужные элементы, но размеры заблудились. Для их восстановления:

dim(z) <- dim(x)[-5] 

(Вы могли бы, очевидно, обернуть это в соответствующей функции.) Тест:

all.equal(y,z) ## TRUE 
Смежные вопросы