Search code examples
rr-factor

Consecutive value after and new level of factor in R


I have the following sample

id <- c("a","b","a","b","a","a","a","a","b","b","c")
SOG <- c(4,4,0,0,0,0,0,0,0,0,9)
data <- data.frame(id,SOG)

I would like in a new column the cumulative value when SOG == 0. with the following code

tmp <- rle(SOG)                                    #run length encoding: 
tmp$values <- tmp$values == 0                      #turn values into logicals 
tmp$values[tmp$values] <- cumsum(tmp$values[tmp$values]) #cumulative sum of TRUE values 
inverse.rle(tmp)                                   #inverse the run length encoding 

I create the column "stop":

data$Stops <- inverse.rle(tmp)

and I can get in it:

[1] 0 0 1 1 1 1 1 1 1 1 0

But I would like to have instead

[1] 0 0 1 2 3 3 3 3 4 4 0 

I mean that when the level of the factor "id" is different from the previous row, I want to jump to the next "stop" (i+1).


Solution

  • We can try

    library(data.table)
    setDT(data1)[, v1 := if(all(!SOG)) c(TRUE, id[-1]!= id[-.N]) else
         rep(FALSE, .N), .(grp = rleid(SOG))][,cumsum(v1)*(!SOG)]
    #[1] 0 0 1 2 3 3 3 3 4 4 0 0 0 0 5 5 0 6 6 0
    

    Using the old data

    setDT(data)[, v1 := if(all(!SOG)) c(TRUE, id[-1]!= id[-.N]) 
           else rep(FALSE, .N), .(grp = rleid(SOG))][,cumsum(v1)*(!SOG)]
    #[1] 0 0 1 2 3 3 3 3 4 4 0
    

    data

    id <- c("a","b","a","b","a","a","a","a","b","b","c","a","a","a","a","a","a","a","a", "a")
    SOG <- c(4,4,0,0,0,0,0,0,0,0,9,1,5,3,0,0,4,0,0,1)
    data1 <- data.frame(id, SOG, stringsAsFactors=FALSE)