R: функция типа apply () для двух двумерных массивов - PullRequest
4 голосов
/ 22 февраля 2011

Я пытаюсь найти функцию типа apply (), которая может запускать функцию, которая работает с двумя массивами вместо одного.

Вроде как:

apply(X1 = doy_stack, X2 = snow_stack, MARGIN = 2, FUN = r_part(a, b))

Данные представляют собой стек групповых массивов из тайлов Landsat, которые собраны вместе с помощью rbind. Каждая строка содержит данные из одной плитки, и в конце мне нужно применить функцию к каждому столбцу (пикселю) данных в этом стеке. Один такой стек содержит информацию о том, есть ли на каждом пикселе снег или нет, а другой - день года для этой строки. Я хочу запустить классификатор (rpart) для каждого пикселя, чтобы он определял день года без снега для каждого пикселя.

То, что я делаю сейчас, довольно глупо: mapply(paste, doy, snow_free) объединяет день года и состояние снега вместе для каждого пикселя в виде строки, apply(strstack, 2, FUN) запускает классификатор для каждого пикселя, и внутри функции apply я взрываю каждую строку, используя strsplit. Как вы можете себе представить, это довольно неэффективно, особенно для 1 миллиона пикселей x 300 плиток.

Спасибо!

Ответы [ 4 ]

9 голосов
/ 22 февраля 2011

Я бы не стал слишком фантазировать. Возможно, вам нужен цикл for.

out <- numeric(n)
for(i in 1:n) {
  out[i] <- snow_free(doy_stack[,i], snow_stack[,i])
}

Или, если вы не хотите вести бухгалтерию самостоятельно,

sapply(1:n, function(i) snow_free(doy_stack[,i], snow_stack[,i]))
2 голосов
/ 01 ноября 2013

Я только что столкнулся с той же проблемой, и, если я ясно понял вопрос, я мог бы решить ее, используя mapply.

Мы будем использовать две матрицы 10x10, заполненные одинаковыми случайными значениями.

set.seed(1)
X <- matrix(runif(100), 10, 10)
set.seed(2)
Y <- matrix(runif(100), 10, 10)

Затем определите, как будут выполняться операции между матрицами.Если это построчно, вам нужно переставить X и Y, а затем привести к data.frame.Это потому, что data.frame - это list со столбцами в качестве элементов списка.mapply() предполагает, что вы передаете list.В этом примере я буду выполнять корреляцию по строкам.

res.row <- mapply(function(x, y){cor(x, y)}, as.data.frame(t(X)), as.data.frame(t(Y)))
res.row[1]
     V1 
0.36788

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

cor(X[1,], Y[1,])
[1] 0.36788

Для операций со столбцами исключить t():

res.col <- mapply(function(x, y){cor(x, y)}, as.data.frame(X), as.data.frame(Y))

Это, очевидно, предполагает, что X и Y имеют размеры, согласующиеся с интересующей операцией (то есть они не должны быть точно такими же размерами).Например, может потребоваться статистический тест по строкам, но с разным количеством столбцов в каждой матрице.

1 голос
/ 23 февраля 2011

Разве не было бы более естественно реализовать это как растровый стек? С пакетом raster вы можете использовать целые растры в функциях (например, ras3 <- ras1^2 + ras2), а также извлекать одно значение ячейки из координат XY или множество значений ячеек, используя маску блока или многоугольника.

0 голосов
/ 22 февраля 2011

apply может работать с более высокими размерами (т.е. list элементы).Не уверен, как ваши данные настроены, но что-то вроде этого может быть то, что вы ищете:

apply(list(doy_stack, snow_stack), c(1,2), function(x) r_part(x[1], x[2]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...