简体   繁体   中英

Count 0s between 1s and group by a variable

I have some precipitation data that I converted into binary, where 1 = a precipitation event and 0 = no precipitation. The data set has over 35,000 values, but here is an example of what my data would look like this:

x = c(1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1)

I would like to count the number of consecutive days without an event, so my output would look like this:

y = 2, 3, 6, 2.

I was given the following answer, which worked great:

with(rle(x), length[!values])
#[1] 2 3 6 2

If we have '0's at the end of the vector, we can start the count from the first 1 to the last 1

x1 <- x[Reduce(':',as.list(range(which(x==1))))]
with(rle(x1), lengths[!values]) 

Now, my question is: is there a way to do this while grouping the data by year? Here is a sample from my data set:

 Event  Year
  1    1916
  1    1916
  0    1916
  0    1916
  0    1916
  1    1916
  0    1916
  0    1916
  0    1916
  1    1916
  0    1917
  0    1917
  0    1917
  0    1917
  0    1917
  1    1917
  0    1917
  1    1917
  1    1917
  1    1917

Based on your previous answer you can likely just use the tapply function. The answer will probably return a list

tapply(data$Event,list(data$Year),
   FUN=function(x) with(rle(x[Reduce(':',as.list(range(which(x==1))))]),lengths[!values]))

or if you've already done your data manipulations

    tapply(data$Event,list(data$Year), FUN=function(x) with(rle(x),lengths[!values]))

We can use data.table

library(data.table)
setDT(df1)[,{x1 <- Event[Reduce(':',as.list(range(which(Event==1))))]
  with(rle(x1), lengths[!values])  }, Year]
#   Year V1
#1: 1916  3
#2: 1916  3
#3: 1917  1

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