简体   繁体   中英

Sum of consecutive rows if they meet a condition

I am using R to analyze a time series containing monthly values of a Drought Index (SPEI). The data has the following structure:

df <- data.frame(
  spei = c(-0.52677,-0.33412, -0.89412 ,0.83459,0.65078,-0.59507,-1.16728,-1.42036,-1.47762,-1.73324,-1.23006,-1.10954), 
  month = c(7:12, 1:6), 
  year = c(rep(1992, 6), rep(1993, 6))
)

I would like to obtain the duration of the drought events based on this definition: number of consecutive months with the index ( spei ) lower than a certain threshold (-0.86 in this case).

Any help?

Here's how I would approach the problem. We use the results from rle to find out how long the current streak is (using lengths from rle ), and then we create a drought variable using values and lengths from rle :

r_l <- rle(df$spei <= -.86) #runs of drought variable

(drought_df <- data.frame(streak = unlist(sapply(r_l$lengths, FUN = function(x) 1:x)),
           drought = rep(r_l$values, r_l$lengths),
           stringsAsFactors = FALSE))

   streak drought
1       1   FALSE
2       2   FALSE
3       1    TRUE
4       1   FALSE
5       2   FALSE
6       3   FALSE
7       1    TRUE
8       2    TRUE
9       3    TRUE
10      4    TRUE
11      5    TRUE
12      6    TRUE

And then you could cbind back to the original table:

cbind(df, drought_df)

       spei month year streak drought
1  -0.52677     7 1992      1   FALSE
2  -0.33412     8 1992      2   FALSE
3  -0.89412     9 1992      1    TRUE
4   0.83459    10 1992      1   FALSE
5   0.65078    11 1992      2   FALSE
6  -0.59507    12 1992      3   FALSE
7  -1.16728     1 1993      1    TRUE
8  -1.42036     2 1993      2    TRUE
9  -1.47762     3 1993      3    TRUE
10 -1.73324     4 1993      4    TRUE
11 -1.23006     5 1993      5    TRUE
12 -1.10954     6 1993      6    TRUE

edit

If you just want the longest streak of droughts, you can use:

max(subset(drought_df, drought)$streak) # subset drought_df for only drought periods
[1] 6

I still don't know the results expected but this also might give an insight:

 transform(df,drought=ave(x<-spei<=-0.86, cumsum(!x), FUN = cumsum))
       spei month year drought
1  -0.52677     7 1992       0
2  -0.33412     8 1992       0
3  -0.89412     9 1992       1
4   0.83459    10 1992       0
5   0.65078    11 1992       0
6  -0.59507    12 1992       0
7  -1.16728     1 1993       1
8  -1.42036     2 1993       2
9  -1.47762     3 1993       3
10 -1.73324     4 1993       4
11 -1.23006     5 1993       5
12 -1.10954     6 1993       6

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM