Применение функции к ребрам многомерного массива в R - PullRequest
0 голосов
/ 21 марта 2012

Как лучше всего применить функцию к краям многомерного массива в R, без предварительного точного кодирования числа измерений.В двумерном массиве я мог бы, например:

myarray[1,] = f(myarray[1,])
myarray[M,] = f(myarray[M,])
myarray[,1] = f(myarray[,1])
myarray[,N] = f(myarray[,N])

Но что, если я хочу, чтобы функция делала это для массива любого измерения?В частности, как я могу справиться с индексацией относительно безболезненно?(Предположим, что многократное применение функции в углах не является проблемой.)

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

Ответы [ 2 ]

1 голос
/ 21 марта 2012

Вот решение, которое должно обрабатывать произвольное количество измерений.Основная идея заключается в том, что

  1. Для каждого измерения вызывается apply() с функцией выбора
  2. Каждый результат этой функции превращается в список длиной один
  3. Это должно заставить apply() возвращать список результатов для каждого измерения
  4. Первый и последний элементы списка для каждого измерения сохраняются в векторе результатов

Это будеточень много времени для массивов с большими размерами и / или отнимающими много времени функциями выбора, поскольку функция применяется к потенциально большому количеству значений, которые не используются.Но он должен учитывать произвольные функции и произвольные результаты этих функций.Вот оно:

## Set up array
xx<-array(1:24,dim=c(1,2,3,4))

## Determine number of dimensions in array
ndim<-length(dim(xx))

## Set up results vector (a list)
myAns<-vector("list",ndim)

## Iterating over the number of dimensions, apply a function
for(ii in seq_len(ndim)){
  tempAns<-apply(xx,ii,function(x)list(mean(x)))
## Store first and last results in myAns vector
## If result is length 1, only store the single result
  if(length(tempAns)==1){
    myAns[[ii]]<-tempAns
  } else {
    myAns[[ii]]<-c(head(tempAns,1),tail(tempAns,1))
  }
}
0 голосов
/ 21 марта 2012

Вы имели в виду что-то подобное?

> ary <- array(1:27, c(3,3,3))
> apply(ary, MARGIN = 3, function(x) {
+             lastColMean <- mean(x[, ncol(x)])
+             lastRowMean <- mean(x[nrow(x), ])
+             data.frame(lastColMean, lastRowMean)
+          })
[[1]]
  lastColMean lastRowMean
1           8           6

[[2]]
  lastColMean lastRowMean
1          17          15

[[3]]
  lastColMean lastRowMean
1          26          24
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...