简体   繁体   中英

R increment by 1 for every change in value column and restart the counter

I would like to find a way to do very similar to this question. Increment by 1 for every change in column

But i want to restart the counter when var1 = c using df$var2 <- with(rle(as.character(df$var1)), rep(seq_along(values), lengths))*

results in column var 2

var1 var2 Should be
   a    1   1
   a    1   1
   1    2   2
   0    3   3
   b    4   4
   b    4   4
   b    4   4
   c    5   1
   1    6   2
   1    6   2

In data.table you can use rleid to get a run-length-id for var1 within each group.

library(data.table)

setDT(df)
df[, var2 := rleid(var1), by = cumsum(var1 == "c")]
df

#    var1 var2
# 1:    a    1
# 2:    a    1
# 3:    1    2
# 4:    0    3
# 5:    b    4
# 6:    b    4
# 7:    b    4
# 8:    c    1
# 9:    1    2
#10:    1    2

and using dplyr

library(dplyr)

df %>%
  group_by(group = cumsum(var1 == "c")) %>%
  mutate(var2 = cumsum(var1 != lag(var1, default = first(var1))) + 1)

data

df <- structure(list(var1 = structure(c(3L, 3L, 2L, 1L, 4L, 4L, 4L, 
5L, 2L, 2L), .Label = c("0", "1", "a", "b", "c"), class = "factor")), 
class = "data.frame", row.names = c(NA, -10L))

We can use the OP's code with rle in base R with ave

df$var2 <- with(df,  as.integer(ave(as.character(var1), cumsum(var1 == 'c'), 
       FUN = function(x) with(rle(x), rep(seq_along(values), lengths)))))
df$var2
#[1] 1 1 2 3 4 4 4 1 2 2

data

df <- structure(list(var1 = structure(c(3L, 3L, 2L, 1L, 4L, 4L, 4L, 
5L, 2L, 2L), .Label = c("0", "1", "a", "b", "c"), class = "factor")), 
class = "data.frame", row.names = c(NA, 
-10L))

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