R StackApply: создание 8-дневного индекса из ежедневных данных с учетом года

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

> seq.Date(as.Date("2001-11-01"), as.Date("2002-01-31"),by=1)
 [1] "2001-11-01" "2001-11-02" "2001-11-03" "2001-11-04" "2001-11-05" "2001-11-06" "2001-11-07"
 [8] "2001-11-08" "2001-11-09" "2001-11-10" "2001-11-11" "2001-11-12" "2001-11-13" "2001-11-14"
[15] "2001-11-15" "2001-11-16" "2001-11-17" "2001-11-18" "2001-11-19" "2001-11-20" "2001-11-21"
[22] "2001-11-22" "2001-11-23" "2001-11-24" "2001-11-25" "2001-11-26" "2001-11-27" "2001-11-28"
[29] "2001-11-29" "2001-11-30" "2001-12-01" "2001-12-02" "2001-12-03" "2001-12-04" "2001-12-05"
[36] "2001-12-06" "2001-12-07" "2001-12-08" "2001-12-09" "2001-12-10" "2001-12-11" "2001-12-12"
[43] "2001-12-13" "2001-12-14" "2001-12-15" "2001-12-16" "2001-12-17" "2001-12-18" "2001-12-19"
[50] "2001-12-20" "2001-12-21" "2001-12-22" "2001-12-23" "2001-12-24" "2001-12-25" "2001-12-26"
[57] "2001-12-27" "2001-12-28" "2001-12-29" "2001-12-30" "2001-12-31" "2002-01-01" "2002-01-02"
[64] "2002-01-03" "2002-01-04" "2002-01-05" "2002-01-06" "2002-01-07" "2002-01-08" "2002-01-09"
[71] "2002-01-10" "2002-01-11" "2002-01-12" "2002-01-13" "2002-01-14" "2002-01-15" "2002-01-16"
[78] "2002-01-17" "2002-01-18" "2002-01-19" "2002-01-20" "2002-01-21" "2002-01-22" "2002-01-23"
[85] "2002-01-24" "2002-01-25" "2002-01-26" "2002-01-27" "2002-01-28" "2002-01-29" "2002-01-30"
[92] "2002-01-31"

Вот как это будет выглядеть, если я упорядочу эти ежедневные значения с 8-дневными интервалами:

> seq.Date(as.Date("2001-11-01"), as.Date("2002-01-31"),by=8)
 [1] "2001-11-01" "2001-11-09" "2001-11-17" "2001-11-25" "2001-12-03" "2001-12-11" "2001-12-19"
 [8] "2001-12-27" "2002-01-04" "2002-01-12" "2002-01-20" "2002-01-28"

Он переносится на следующий год так же, как и от одного месяца к другому (ежемесячный перенос — это нормально). Это только часть проблемы, потому что я хотел бы, чтобы конечным продуктом был индекс, который я мог бы использовать в StackApply. Итак, взяв 8-дневный пример выше, индекс должен выглядеть так:

> rep(1:12,times=c(8,8,8,8,8,8,8,5,8,8,8,7))
 [1]  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2  3  3  3  3  3  3  3  3  4  4  4  4  4  4  4
[32]  4  5  5  5  5  5  5  5  5  6  6  6  6  6  6  6  6  7  7  7  7  7  7  7  7  8  8  8  8  8  9
[63]  9  9  9  9  9  9  9 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 12 12 12 12 12 12 12

Обратите внимание на цифру 5 в середине команды, которая указывает, что она останавливается на 31 декабря 2001 года и не переходит на 2002 год. Таким образом, я хочу создать индекс, который имеет одно целое число для каждого 8-дневного интервала в течение года. но это не переносится на следующий год. У меня есть растровый стек ежедневных данных за более чем 20 лет, поэтому это будет очень длинный индекс.

Заранее спасибо за помощь!


person lamochila    schedule 19.12.2018    source источник
comment
Объединение lubridate::yday() и %% 8 решит вашу проблему?   -  person Michael Bird    schedule 19.12.2018
comment
Вы имеете в виду это lubridate::yday(x = seq.Date(as.Date("2001-11-01"), as.Date("2002-01-31"),by=1)) %% 8? Вывод близок, но не совсем таким, каким должен быть индекс.   -  person lamochila    schedule 19.12.2018
comment
dat <- seq.Date(as.Date("2001-11-01"), as.Date("2002-01-31"),by=1); ref <- seq.Date(as.Date("2001-11-01"), as.Date("2002-01-31"),by=8); out <- sapply(dat,function(x){sum(x - ref >=0)}) действительно близко, но я не уверен, почему вы хотите, чтобы 2002-01-01 было 2002-01-04, когда все остальное округляется в меньшую сторону.   -  person Michael Bird    schedule 19.12.2018


Ответы (1)


arrow_upward
0
arrow_downward

Возможно, это обходной путь, но это должно работать:

library(dplyr)
library(lubridate)
df <- data.frame(date = seq.Date(as.Date("2000-01-01"), as.Date("2010-12-31"), "day"))

df %>%
  mutate(year = year(date)) %>%
  group_by(year) %>%
  mutate(index = rep(seq_along(df$date), each = 8)[1:max(yday(date))]) %>%
  ungroup() %>%
  mutate(index = index + 46 * (year - min(year)))
person Lennyy    schedule 19.12.2018
comment
Добро пожаловать. Кстати, только что понял, что это работает только в том случае, если у вас нет пропущенных дат и каждый год начинается 1 января и заканчивается 31 декабря. Этот код, конечно, может быть изменен для более общих случаев. - person Lennyy; 19.12.2018
comment
Ты прав. Я также понял, что я не просеивал все свои точки данных на предмет пропущенных значений, потому что 8-дневные интервалы кажутся в целом согласованными. Что касается дат, они начинаются 1 января и заканчиваются 31 декабря, но, как вы сказали, я могу изменить сценарий. @Lennyy, возможно, вы можете отредактировать свой ответ, чтобы он отражал эти другие сценарии на случай, если у кого-то возникнет немного другая, но в целом похожая проблема? - person lamochila; 19.12.2018