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