как использовать aaply и сохранить порядок размеров в массиве?

У меня есть массив с 3 измерениями. Я хотел бы применить функцию к 3-му измерению и вернуть массив. Мне было очень приятно, что plyr :: aaply делает почти то, что я хочу. Однако он меняет размеры моего массива. В документации мне говорилось, что он идемпотентен, что (после того, как я его просмотрел) заставляет меня думать, что структура должна оставаться такой же. Вот воспроизводимый пример с функцией идентичности. Могу ли я изменить это, чтобы сохранить порядок размеров массива?

nRow <- 10
nCol <- 10
nAge <- 7

#creating the array
dimnames <- list(NULL,NULL,NULL)
names(dimnames) <- c("x","y","age")
aF <- array(0, dim=c(nCol,nRow,nAge), dimnames=dimnames)

#aaply the identity function to the 3rd dimension
aTst <- aaply(aF, .margins=3, identity )

dim(aF)
#[1] 10 10  7
dim(aTst)
#[1]  7 10 10

См. Размеры изменены с 10,10,7 на 7,10,10. Я знаю, что его можно вернуть обратно с помощью аперма, но если я смогу этого избежать, было бы хорошо.

aTst2 <- aperm(aTst, c(2, 3, 1))

Вот еще несколько подробностей о том, что я на самом деле пытаюсь с этим сделать (спасибо @Simon O'Hanlon). x и y представляют собой 2D-пространство, и у меня есть вектор возрастов в каждой ячейке сетки. Я хочу переместить каждую возрастную группу, используя эту функцию:

rtMove1 <- function(m, pMove=0.4) {

  #create matrices of the 4 neighbour cells to each cell
  mW = cbind( rep(0,nrow(m)), m[,-nrow(m)] )
  mN = rbind( rep(0,ncol(m)), m[-ncol(m),] )
  mE = cbind( m[,-1], rep(0,nrow(m)) )
  mS = rbind( m[-1,], rep(0,ncol(m)) )

  mArrivers <- pMove*(mN + mE + mS + mW)/4
  mStayers <- (1-pMove)*m

  mNew <- mArrivers + mStayers
  return( mNew )
}

Чтобы запустить popn, переместите все возрасты во все ячейки, которые я могу сделать.

#initiate 100 individuals of age 3 at 5,5
aF[5,5,3] <- 100

aTst <- aaply(aF, .margins=3, rtMove1 )

aTst[3,,]

Это работает при перераспределении popn:

     1 2 3  4  5  6 7 8 9 10
  1  0 0 0  0  0  0 0 0 0  0
  2  0 0 0  0  0  0 0 0 0  0
  3  0 0 0  0  0  0 0 0 0  0
  4  0 0 0  0 10  0 0 0 0  0
  5  0 0 0 10 60 10 0 0 0  0
  6  0 0 0  0 10  0 0 0 0  0
  7  0 0 0  0  0  0 0 0 0  0
  8  0 0 0  0  0  0 0 0 0  0
  9  0 0 0  0  0  0 0 0 0  0
  10 0 0 0  0  0  0 0 0 0  0

Но мне нужно использовать аперм, чтобы переставить размеры, если я хочу повторить.

Спасибо, Энди


person Andy    schedule 05.06.2014    source источник
comment
Идемпотентность означает, что она остается неизменной при последующих вызовах: т.е. f ^ n (x) = f (x).   -  person James    schedule 05.06.2014
comment
Какую функцию вы на самом деле хотите применить? Знаете ли вы, что функция base::apply может работать с любым количеством измерений массива? apply( aF , 1:3 , identity ) или например apply( aF , 3 , sum ) дает вам сумму каждой из двухмерных матриц в 3-м измерении (в данном случае вектор 7 0s).   -  person Simon O'Hanlon    schedule 05.06.2014


Ответы (1)


Вы могли бы попробовать

aTst <- aaply(aF, c(1,2,3), identity)

Это должно делать свое дело

person arvind    schedule 05.06.2014
comment
Это вернет список ... @Andy - взамен нужен массив, - четко упомянул он. - person vrajs5; 05.06.2014