Применить функцию к следующей строке на основе предыдущей для разных идентификаторов в R

#r #dataframe #for-loop #binary

#r #dataframe #для цикла #двоичный

Вопрос:

Я хотел бы применить функцию для разных идентификаторов df, в которой, если следующая строка отличается от предыдущей, тогда верните 1, иначе верните 0.

Я совершенно не понимаю, как я мог бы этого добиться, есть ли способ это сделать?

Вот структура данных:

 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

  

Ожидаемый результат должен выглядеть следующим образом:

 #  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
  

Ответ №1:

Мы могли бы сгруппироваться по «id», создать «changing_job_position» на основе любого duplicated или n_distinct(job_position) >1 вместе с row_number и затем ungroup и взять lead «changing_job_position»

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

-вывод

 # 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
  

Комментарии:

1. Мне просто нужно было изменить ungroup ungroup() , и это работает отлично! спасибо @akrun!

2. @AlvaroMartinez я думаю, что некоторые из проблем, о которых вы упоминали в моих предыдущих решениях, могут быть связаны с версией пакета, ungroup которая работает для меня

Ответ №2:

Для каждого id вы можете проверить, отличается ли текущее значение от предыдущего значения.

 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
  

Используя data.table , вы можете сделать :

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