Apply a function to next row based on previous one for distinct id's in R

Viewed 36

I would like to apply a function for distinct df id's, in which if next row is distinct of previous one then return 1 else return 0.

I have completely no clue of how could I achieve this, Is there anyway to accomplish it?

Here's the data structure:

df <- structure(list(
      id = c(2,2,3,3,4,4,5,5),
      job_position = c("Analyst", "Supervisor",
                       "HRBP", "HRBP", "Economist",
                       "Financial Planner", "Reporter",
                       "Reporter")),
      class = "data.frame",
      row.names = c(NA, -8L))
))

#  id    job_position
#   2       Analyst
#   2      Supervisor
#   3        HRBP
#   3        HRBP
#   4      Economist
#   4      Financial Planner
#   5       Reporter
#   5       Reporter

Expected output should look like this:

#  id    job_position         changing_job_position
#   2       Analyst                   0
#   2      Supervisor                 1
#   3        HRBP                     0
#   3        HRBP                     0
#   4      Economist                  0
#   4      Financial Planner          1 
#   5       Reporter                  0
#   5       Reporter                  0
2 Answers

We could group by 'id', create the 'changing_job_position' based on any duplicated or n_distinct(job_position) >1 along with the row_number and then ungroup and take the lead of the 'changing_job_position'

library(dplyr)
df %>%
    group_by(id) %>% 
    mutate(changing_job_position = + (any(duplicated(job_position)) &
          row_number() == 1)) %>% 
    ungroup %>% 
    mutate(changing_job_position = lead(changing_job_position, default = 0))

-output

# A tibble: 8 x 3
#     id job_position      changing_job_position
#  <dbl> <chr>                             <dbl>
#1     2 Analyst                               0
#2     2 Supervisor                            1
#3     3 HRBP                                  0
#4     3 HRBP                                  0
#5     4 Economist                             0
#6     4 Financial Planner                     1
#7     5 Reporter                              0
#8     5 Reporter                              0

For each id you can check if the current value is different than the previous value.

library(dplyr)

df %>%
  group_by(id) %>%
  mutate(changing_job_position = +(job_position != lag(job_position, 
                                   default = first(job_position))))

#    id job_position      changing_job_position
#  <dbl> <chr>                             <int>
#1     2 Analyst                               0
#2     2 Supervisor                            1
#3     3 HRBP                                  0
#4     3 HRBP                                  0
#5     4 Economist                             0
#6     4 Financial Planner                     1
#7     5 Reporter                              0
#8     5 Reporter                              0

Using data.table you can do :

library(data.table)
setDT(df)[, changing_job_position := +(job_position != shift(job_position,
                                       fill = first(job_position))), id]
Related