簡體   English   中英

計算兩個日期之間的負值數

[英]Calculate number of negative values between two dates

我有一個 SPEI 值的數據框。 我想以間隔計算兩個統計數據(如下所述)

  1. 20年即2021-2040、2041-2060、2061-2080、2081-2100。 第一列包含日期(月-年),以及
  2. 每年,即 2021 年、2022 年、2023 年等,直到 2100 年。

統計數據如下:

  1. 干旱頻率:指定時期(分別為20年和1年)SPEI<0的次數
  2. 干旱持續時間:等於指定時期的開始(包括)和結束月份(不包括)之間的月數。 我假設干旱事件在 SPEI < 0 時開始。

我想知道在 R 中是否有辦法做到這一點? 這似乎是一個簡單的問題,但我不知道該怎么做。 請幫幫我。 Excel 花費的時間太長。 謝謝。

> head(test, 20)
         Date      spei-3
1  2021-01-01          NA
2  2021-02-01          NA
3  2021-03-01 -0.52133737
4  2021-04-01 -0.60047887
5  2021-05-01  0.56838399
6  2021-06-01  0.02285012
7  2021-07-01  0.26288462
8  2021-08-01 -0.14314685
9  2021-09-01 -0.73132256
10 2021-10-01 -1.23389220
11 2021-11-01 -1.15874943
12 2021-12-01  0.27954143
13 2022-01-01  1.14606657
14 2022-02-01  0.66872986
15 2022-03-01 -1.13758050
16 2022-04-01 -0.27861017
17 2022-05-01  0.99992395
18 2022-06-01  0.61024314
19 2022-07-01 -0.47450485
20 2022-08-01 -1.06682997

編輯:我非常喜歡添加一些代碼,但我不知道從哪里開始。

test = "E:/drought.xlsx"
#Extract year and month and add it as a column
test$Year =  format(test$Date,"%Y")
test$Month = format(test$Date,"%B")

我不知道如何從這里 go 。 我發現cumsum可以提供幫助,但是我如何 select 一年然后應用cumsum就可以了。 我不是故意隱瞞代碼。 我只是不知道從哪里或如何開始。

OP的帖子有幾個問題,所以我將逐步通過它們 go 。 您需要dplyr並為此工作流程進行lubridate

首先,我們創建一些假數據來使用:

library(lubridate)
library(dplyr)
#create example data
dd<- data.frame(Date = seq.Date(as.Date("2021-01-01"), as.Date("2100-12-01"), by = "month"),
                      spei = rnorm(960,0,2))

看起來像這樣,類似於您上面的內容

> head(dd)
        Date        spei year   year_20 drought
1 2021-01-01 -6.85689789 2021 2021_2040       1
2 2021-02-01 -0.09292459 2021 2021_2040       1
3 2021-03-01  0.13715922 2021 2021_2040       0
4 2021-04-01  2.26805601 2021 2021_2040       0
5 2021-05-01 -0.47325008 2021 2021_2040       1
6 2021-06-01  0.37034138 2021 2021_2040       0

然后我們可以使用 lubridate 和 cut 創建我們的年度和 20 年變量以便稍后分組,並創建一個表示spei是否為負的列drought

#create a column to group on by year and by 20-year
dd <- dd %>%
  mutate(year  = year(Date),
         year_20 = cut(year, breaks = c(2020,2040,2060,2080, 2100), include.lowest = T,
                       labels = c("2021_2040", "2041_2060", "2061_2080", "2081_2100")))  %>%
  #column signifying if that month was a drought
  mutate(drought = ifelse(spei<0,1,0))

一旦我們有了它,我們只需使用group_by function 來獲得按年或 20 年的頻率(或干旱的月數)

#by year
dd %>%
  group_by(year) %>%
  summarise(year_freq = sum(drought)) %>%
  ungroup()

# A tibble: 80 x 2
    year year_freq
   <dbl>     <dbl>
 1  2021         6
 2  2022         4
 3  2023         7
 4  2024         6
 5  2025         6
 6  2026         7

#by 20-year group
dd %>%
  group_by(year_20) %>%
  summarise(year20_freq = sum(drought)) %>%
  ungroup()

# A tibble: 4 x 2
  year_20   year20_freq
  <fct>           <dbl>
1 2021_2040         125
2 2041_2060         121
3 2061_2080         121
4 2081_2100         132

計算干旱持續時間有點復雜。 它涉及

  1. 確定每次干旱的第一個月
  2. 計算每次干旱的長度
  3. 將來自 1 和 2 的信息組合在一起

我們可以使用lag來確定一個月從“無干旱”變為“干旱”的時間。 在這種情況下,我們想要一個索引,其中第i行中的值與第i-1行中的值不同

# find index of where values change. 
change.ind <- dd$drought != lag(dd$drought)
#use index to find drought start
drought.start <- dd[change.ind & dd$drought == 1,]

這會產生初始數據集的子集,但僅包含干旱第一個月的行。 然后我們可以使用rle來計算干旱的長度。 rle將計算每個數字運行的長度,因此我們必須僅對那些值==1(干旱)的運行進行子集化

#calculate drought lengths
drought.lengths <- rle(dd$drought)
# we only want droughts (values = 1)
drought.lengths <- drought.lengths$lengths[drought.lengths$values==1]

現在我們可以將這兩條信息組合在一起。 第一行是NA ,因為i-1處沒有可比較滯后的值。 它可以被刪除,除非您想包含該數據。

drought.dur <- cbind(drought.start, drought_length = drought.lengths)
head(drought.dur)
         Date        spei year   year_20 drought drought_length
NA       <NA>          NA   NA      <NA>      NA              2
5  2021-05-01 -0.47325008 2021 2021_2040       1              1
9  2021-09-01 -2.04564549 2021 2021_2040       1              1
11 2021-11-01 -1.04293866 2021 2021_2040       1              2
14 2022-02-01 -0.83759671 2022 2021_2040       1              1
17 2022-05-01 -0.07784316 2022 2021_2040       1              1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM