我有一组包含每天降水总量 (Precip) 的数据。我在多个池子收集了数据。我需要计算自上次降水量超过 12 毫米以来的天数。如果当天的降雨量超过 12 毫米,则结果为“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)
我需要以下数据框:
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
我可以轻松添加一列来指示降水量是否超过 12:
df2 <- df %>%
group_by(Pool) %>%
mutate(pre12=ifelse(Precip>12,1,0))
但是我不确定当 pre12==1 时如何计算 DATE 和前一个日期之间的天数
这里的许多答案都忽略了日期列中的值,而是恢复为“计算行数”,因此需要非常干净的数据 - 您的示例提供了 - 每天一行,没有缺失值,一切有序。
直接使用日期可以提供一种更可靠的方法。以下是其中一种方法:
你已经有了一个很好的开端
if_else()
,但我们可以更进一步。我们不要简单地在那里捕捉真/假,而是记录任何降水量 > 12 的日期的实际日期。这是确定最近降水量 > 12 的日期的第一步。然后我们可以使用
tidyr::fill()
(它足够智能,可以保持在 group_by() 定义的组中)将最后一个非缺失值填充到所有 NA 中,以获取给定池的最新日期的列,其中 precip > 12。这里的数据需要按递增顺序排列,以便填充达到我们想要的效果,所以不要忘记arrange
保护你的后方!然后我们可以对这两列使用实际日期数学来计算自上次下雨以来经过的时间。
因为我们正在进行日期数学运算,并且我们已经安排好了数据,所以这种方法对于缺失和无序数据具有很强的鲁棒性。
你可以这样做:
其结果为:
假设您的数据按日期排序。另外,我没有考虑 Pool 变量,您可能也想根据该变量进行分组。
假设您有每天的数据,使用
cumsum
和row_number
。由于第二组第一组NA
相当随意(也可以是 0),因此它需要自己的规则。如果有日期差距