Creating a new column conditionally based on previous n rows
In base R, we can use ave
grouped by id
and Location
and turn all the values from second row of the group to 1.
df$Flag <- as.integer(with(df, ave(Encounter, id, Location, FUN = seq_along) > 1))
df
# id Location Encounter Flag
#1 111 A 1 0
#2 111 B 2 0
#3 111 A 3 1
#4 222 A 1 0
#5 222 C 2 0
#6 222 B 3 0
#7 222 A 4 1
#8 333 B 1 0
#9 333 A 2 0
#10 333 A 3 1
#11 333 A 4 1
Using dplyr
, that would be
library(dplyr)
df %>% group_by(id, Location) %>% mutate(Flag = as.integer(row_number() > 1))
Using data.table
:
library(data.table)
dt[, flag:=1]
dt[, flag:=cumsum(flag), by=.(id,Location)]
dt[, flag:=ifelse(flag>1,1,0)]
Data:
dt <- data.table("id" = c(111,111,111,222,222,222,222,333,333,333,333),
"Location" = c("A","B","A","A","C","B","A","B","A","A","A"),
"Encounter" = c(1,2,3,1,2,3,4,1,2,3,4))
A more generic data.table
solution would be using .N
or rowid
:
library(data.table)
setDT(dt)[, Flag := +(rowid(id, Location)>1)][]
or
setDT(df)[, Flag := +(seq_len(.N)>1), .(id, Location)][]
#> id Location Encounter Flag
#> 1: 111 A 1 0
#> 2: 111 B 2 0
#> 3: 111 A 3 1
#> 4: 222 A 1 0
#> 5: 222 C 2 0
#> 6: 222 B 3 0
#> 7: 222 A 4 1
#> 8: 333 B 1 0
#> 9: 333 A 2 0
#> 10: 333 A 3 1
#> 11: 333 A 4 1
An option with duplicated
library(dplyr)
df %>%
group_by(id) %>%
mutate(Flag = +(duplicated(Location)))
# A tibble: 11 x 4
# Groups: id [3]
# id Location Encounter Flag
# <dbl> <fct> <dbl> <int>
# 1 111 A 1 0
# 2 111 B 2 0
# 3 111 A 3 1
# 4 222 A 1 0
# 5 222 C 2 0
# 6 222 B 3 0
# 7 222 A 4 1
# 8 333 B 1 0
# 9 333 A 2 0
#10 333 A 3 1
#11 333 A 4 1