Tenho um conjunto de dados com totais de precipitação (Precip) para cada dia. Coletei dados em vários pools. Preciso calcular quantos dias se passaram desde a última vez que choveu> 12 mm. Se choveu mais de 12 mm naquele dia, receberá um '0'.
## creates example dataframe
Pool <- c("A","A","A","A","A","A","A","A","A","A",
"B","B","B","B","B","B","B","B","B","B")
DATE <- as.Date(c("2005-01-01","2005-01-02","2005-01-03","2005-01-04","2005-01-05",
"2005-01-06","2005-01-07","2005-01-08","2005-01-09","2005-01-10",
"2005-01-01","2005-01-02","2005-01-03","2005-01-04","2005-01-05",
"2005-01-06","2005-01-07","2005-01-08","2005-01-09","2005-01-10"))
Precip <- c(0,0,3,18,4,3,13,8,3,0,13,0,3,13,0,3,10,8,13,0))
df <- data.frame(Pool, DATE, Precip)
Preciso do seguinte dataframe:
Pool DATE Precip Days_since12
1 A 2005-01-01 0 NA
2 A 2005-01-02 0 NA
3 A 2005-01-03 3 NA
4 A 2005-01-04 18 NA
5 A 2005-01-05 4 1
6 A 2005-01-06 3 2
7 A 2005-01-07 13 0
8 A 2005-01-08 8 1
9 A 2005-01-09 3 2
10 A 2005-01-10 0 3
11 B 2005-01-01 13 0
12 B 2005-01-02 0 1
13 B 2005-01-03 3 2
14 B 2005-01-04 13 0
15 B 2005-01-05 0 1
16 B 2005-01-06 3 2
17 B 2005-01-07 10 3
18 B 2005-01-08 8 4
19 B 2005-01-09 13 0
20 B 2005-01-10 0 1
Posso facilmente adicionar uma coluna para indicar se o precipitado foi superior a 12 ou não:
df2 <- df %>%
group_by(Pool) %>%
mutate(pre12=ifelse(Precip>12,1,0))
Mas não tenho certeza de como calcular o número de dias entre DATE e a data anterior quando pre12==1
Muitas das respostas aqui ignoram o valor na coluna de data, em vez disso revertem para "contar linhas" e, portanto, exigem dados muito limpos - que seu exemplo fornece - uma linha por dia, sem valores ausentes, tudo em ordem.
Usar as datas diretamente fornece uma abordagem mais robusta. Aqui está uma maneira:
Você começou bem com
if_else()
, mas podemos ir mais longe. Em vez de simplesmente capturar um verdadeiro/falso, vamos registrar a data real para qualquer dia com precipitação > 12. Este é o primeiro passo para determinar o dia mais recente com precipitação > 12.Então podemos usar
tidyr::fill()
(que é inteligente o suficiente para permanecer dentro dos grupos definidos por group_by()) para preencher o último valor não ausente em todos os NAs, para obter uma coluna da data mais recente com precipitação> 12 para um determinado pool. Os dados precisam estar em ordem crescente aqui para que o preenchimento faça o que queremos, então não se esqueça dearrange
se proteger!Então podemos usar a matemática da data real nessas duas colunas para calcular o tempo decorrido desde a última chuva.
Como estamos fazendo cálculos de datas e organizando nossos dados, essa abordagem é robusta para dados ausentes e fora de ordem.
Você poderia fazer:
o que dá:
A suposição é que seus dados sejam classificados por data. Além disso, não levei em consideração a variável Pool, pela qual você também pode querer agrupar.
Supondo que você tenha dados diários, use
cumsum
erow_number
. Como o segundo grupoNA
é bastante arbitrário (também pode ser 0), ele precisa de sua própria regra.Se houver lacunas em DATE