Условное извлечение данных из данных стека растра на основе значений в кадре данных пространственных точек

У меня есть растровый стек, содержащий 84 слоя, каждый из которых соответствует 1 месяцу осадков с ноября 1999 года по октябрь 2006 года. Я назвал слои в моем растровом стеке с 199911 по 200610, то есть год, за которым следует месяц. У меня также есть фреймворк пространственных точек, где каждая строка имеет дату в идентичном формате.

Я хочу извлечь из растрового стека сумму всех осадков между датой создания ряда и предыдущим октябрем в пространственном местоположении этого ряда. Таким образом, если датой строки является 20006 (июнь 2000 года), она суммирует все количество осадков в этой строке за период с 199910 (октябрь 1999) по 20006 год. Поскольку у меня много данных, я хочу автоматизировать этот процесс.

Я пытался заставить это работать, но без всякой радости. Есть ли у кого-нибудь советы?


person James    schedule 19.04.2016    source источник


Ответы (1)


Вот один вариант:

library(raster)

# Vector of dates
dates <- format(seq(as.Date('1999/1/11'), as.Date('2006/1/10'), by='month'), '%Y%m')

# RasterStack with random data
s <- setNames(stack(replicate(length(dates), raster(matrix(runif(100), 10)))), 
              paste0('rain', dates))

# Create a SpatialPointsDataFrame with some random dates and coords
d <- data.frame(x=runif(10), y=runif(10), date=sample(dates, 10))
coordinates(d) <- ~x+y

# Split the spdf by date
d_by_date <- split(d, d$date)

# Extract values
rain_sum <- unsplit(lapply(d_by_date, function(x) {
  # current year
  y <- as.numeric(substr(x$date, 1, 4))
  # current month
  m <- as.numeric(substr(x$date, 5, 6))
  # if month is after Oct, start from that year's Oct
  # if month is before Oct, start from previous year's Oct
  if(m < 11) y <- y-1
  start_date <- as.Date(sprintf('%s/10/01', y))
  # if start_date is earlier than first time slice, reset to first time slice
  start_date <- max(min(as.Date(sub('rain', '01', names(s)), '%d%Y%m')), start_date)
  end_date <- as.Date(paste0(x$date, '01'), '%Y%m%d')
  # Sequence of dates to sum over
  i <- format(seq(start_date, end_date, by='month'), 'rain%Y%m')
  # Extract values and sum
  sum(extract(s[[i]], x))
}), d$date)
person jbaums    schedule 22.04.2016
comment
Спасибо за помощь jbaums! К сожалению, я не могу заставить код работать для меня, я получаю и предупреждение, и ошибку. Я думаю, что оператор if проверяет только первую запись, поэтому я попробую написать цикл for и посмотрю, поможет ли это. Предупреждение: в if (m ‹11) y‹ - y - 1: условие имеет длину ›1 и будет использоваться только первый элемент. Ошибка в формате (seq (start_date, end_date, by = month), rain% Y% m): ошибка при оценке аргумента 'x' при выборе метода для функции 'format': Ошибка в seq.Date (start_date, end_date, by = month): 'to' должно иметь длину 1 - person James; 26.04.2016
comment
У меня есть код, который будет работать на меня, и я отредактировал ваш ответ, чтобы отразить внесенные мной изменения. В частности, я поменял ваше lapply на цикл for. Приняли ваш ответ. - person James; 28.04.2016
comment
За исключением того, что мое правка не была принята по какой-то причине ... разберись. - person James; 29.04.2016