Al Mac
Al Mac

Reputation: 93

Fill in rows based on condition for grouped data using tidyr

I have the following dataframe of which I am trying to create the 'index2' field conditional on the 'index1' field: enter image description here

Basically this data represents a succession of behaviours for different individual (ID) penguins and I am trying to index groups of behaviour (index 2) that incorporates all other behaviours in between (and including) dives (which have been indexed into dive bouts = index 1). I would appreciate a tidyverse solution grouping by ID.

Reproducible: 
df<-data.frame(ID=c(rep('A',9),rep('B',14)),behaviour=c('surface','dive','dive','dive','surface','commute','surface','dive',   'dive','dive','dive','surface','dive','dive','commute','commute','surface','dive','dive','surface','dive','dive','surface'),index1=c(0,1,1,1,0,0,0,1,1,2,2,0,3,3,0,0,0,3,3,0,3,3,0),index2=c(0,1,1,1,1,1,1,1,1,2,2,0,3,3,3,3,3,3,3,3,3,3,0))

Upvotes: 0

Views: 289

Answers (1)

akrun
akrun

Reputation: 887881

We could create a function with rle

frle <- function(x) {
    rl <- rle(x)
    i1 <- cummax(rl$values)
    i2 <- c(i1[-1]  != i1[-length(i1)], FALSE)
    i1[i2] <- 0
    as.integer(inverse.rle(within.list(rl, values <- i1)))
 }

After grouping by 'ID', mutate the 'Index1' to get the expected column

library(dplyr) 
df1 %>% 
  group_by(ID) %>%
  mutate(Index2New = frle(Index1))
# A tibble: 19 x 5
# Groups: ID [2]
#   ID    behaviour Index1 Index2 Index2New
#   <chr> <chr>      <int>  <int>     <int>
# 1 A     surface        0      0         0
# 2 A     dive           1      1         1
# 3 A     dive           1      1         1
# 4 A     dive           1      1         1
# 5 A     surface        0      1         1
# 6 A     commute        0      1         1
# 7 A     surface        0      1         1
# 8 A     dive           1      1         1
# 9 A     dive           1      1         1
#10 B     dive           2      2         2
#11 B     dive           2      2         2
#12 B     surface        0      0         0
#13 B     dive           3      3         3
#14 B     dive           3      3         3
#15 B     commute        0      3         3
#16 B     commute        0      3         3
#17 B     surface        0      3         3
#18 B     dive           3      3         3
#19 B     dive           3      3         3

Upvotes: 1

Related Questions