R: массивы - уменьшение длины (обобщение)

Мне нужно уменьшить длину (обобщить) массива в R. Например, у меня есть данные с высоким разрешением, как это...

my_array=array(c(sample(0:9,32, replace=TRUE)), dim=c(4,4,2))
> my_array
, , 1

     [,1] [,2] [,3] [,4]
[1,]    2    1    8    2
[2,]    3    5    4    6
[3,]    2    8    9    6
[4,]    1    0    9    9

, , 2

     [,1] [,2] [,3] [,4]
[1,]    3    7    9    7
[2,]    9    4    9    8
[3,]    8    6    7    8
[4,]    7    6    9    9

... и мне нужно "обобщить" его до низкого разрешения, используя функцию средних значений, например:

, , 1

     [,1] [,2]
[1,] 2.75 4.00
[2,] 2.75 8.25

, , 2

     [,1] [,2]
[1,] 5.75 8.25
[2,] 6.75 8.25

Просто 4 значения исходного массива (позиции [1,1];[1,2];[2,1];[2,2]) образуют 1 значение (среднее) в результирующем массиве в позиции [1,1], Я пытался использовать "apply" для массива, но я не в состоянии справиться с "нестандартными" полями. Есть ли более сложные функции, такие как apply в R?

2 ответа

Решение

Вот решение, очень похожее на решение, адаптированное @crwang, но обобщенное в функцию:

reduceMatrix <- function(x, rown, coln, fun = mean, ...) {
  out <- matrix(NA,  nrow=nrow(x)/rown, ncol=ncol(x)/coln)
  for (i in 1:(nrow(x)/rown)) {
    for (j in 1:(ncol(x)/coln)) {
      indi <- c(rown*i-1, rown*i)
      indj <- c(coln*j-1, coln*j)
      out[i, j] <- fun(x[indi, indj], ...)  
    }
  }
  out
}

Функция работает с 2-мерными массивами, поэтому вы можете применять их к 3-му измерению my_array:

set.seed(10)
my_array <- array(c(sample(0:9,32, replace=TRUE)), dim=c(4,4,2))

lapply(seq_len(dim(my_array)[3]), 
       function(a) reduceMatrix(my_array[,,a], 2, 2))

[[1]]

     [,1] [,2]
[1,]  2.5  4.0
[2,]  3.5  4.5

[[2]]
     [,1] [,2]
[1,] 4.00 5.25
[2,] 5.25 3.75

Идея этого подхода состоит в том, чтобы иметь функцию, которая работает либо для автономных матриц (в трехмерных массивах, списках и т. Д.), А также для облегчения выбора количества строк (rown) и столбцы (coln) для агрегирования, а также применяемой функции (mean, median, sum) и другие аргументы (например, na.rm).

Я хотел это прокомментировать, но у меня недостаточно репутации, поэтому я оставляю свой комментарий здесь.

Я нашел похожий вопрос и ответ здесь.

Решение вашей проблемы, основанное на ответе, который я нашел, может быть:

my_array=array(c(sample(0:9,32, replace=TRUE)), dim=c(4,4,2))
my_array

rmean <- array(c(matrix(0,2,2),matrix(0,2,2)),dim=c(2,2,2))  # result array
for (i in 1:2){
  for (j in 1:2){
    for (k in 1:2){
      rmean[,,k][i, j] <- mean(my_array[,,k][c(-1,0) + 2 * i, c(-1,0) + 2 * j])
    }
  }
}
rmean

Результаты:

> my_array
, , 1

     [,1] [,2] [,3] [,4]
[1,]    8    4    4    9
[2,]    0    7    9    5
[3,]    2    7    2    6
[4,]    9    5    8    6

, , 2

     [,1] [,2] [,3] [,4]
[1,]    2    1    4    7
[2,]    3    7    0    6
[3,]    2    8    9    3
[4,]    7    9    1    9

> rmean
, , 1

     [,1] [,2]
[1,] 4.75 6.75
[2,] 5.75 5.50

, , 2

     [,1] [,2]
[1,] 3.25 4.25
[2,] 6.50 5.50
Другие вопросы по тегам