#r
#r
Вопрос:
У меня есть такой фрейм данных:
d=data.frame('Id'=c(101,101,101,101,103,103,103),
'Action'=c('hire','terminate','promoted','promoted','hire','promoted','terminate'),
'date'=c('02/22/2017','12/11/2020','11/11/2018','03/22/2019','02/23/2016','01/12/2018','03/21/2019'))
Я хочу создать новый столбец time_spent
, который вычисляет день между датой найма и датой окончания, а также датой найма и датой повышения.
df$date=mdy(df$date)
df %>%
mutate(date = as.Date(EFFDT)) %>%
group_by(EMPLID) %>%
summarise(time_spent = as.numeric(difftime(EFFDT[ACTION == 'TER'], EFFDT[ACTION == 'HIR'], units = 'days')))%>%
inner_join(df,by='EMPLID')
Приведенный выше код вычисляет время, но оно находится между наймом и завершением. Что мы можем сделать для найма и продвижения по службе?
Также, если мы видим, что для Id
101 продвижение происходит дважды, у нас есть две разные даты. Итак, если мы применим приведенный выше код для найма и продвижения, он вычисляет только дни между наймом и первым появлением продвигаемого действия для Id
101, а не все продвигаемые действия, которые произошли для Id
101.
Ответ №1:
Возможно, это может быть полезно. Вместо summarise
и inner_join
вы можете использовать mutate
и, чтобы новый столбец time_spent
был разницей во времени между этой строкой date
и date
тем, когда человек был нанят.
library(tidyverse)
d %>%
mutate(date = as.Date(date, format = "%m/%d/%Y")) %>%
arrange(Id, date) %>%
group_by(Id) %>%
mutate(time_spent = difftime(date, date[Action == "hire"], units = "days"))
Вывод
Id Action date time_spent
<dbl> <chr> <date> <drtn>
1 101 hire 2017-02-22 0 days
2 101 promoted 2018-11-11 627 days
3 101 promoted 2019-03-22 758 days
4 101 terminate 2020-12-11 1388 days
5 103 hire 2016-02-23 0 days
6 103 promoted 2018-01-12 689 days
7 103 terminate 2019-03-21 1122 days
Редактировать: если вы хотите включить NA
, когда дата «найма» недоступна, вы можете filter
включить Id
any
дату «найма», а затем снова объединить данные. Сначала просто убедитесь, что фрейм данных имеет date
правильный формат.
d$date <- as.Date(d$date, format = "%m/%d/%Y")
d %>%
arrange(Id, date) %>%
group_by(Id) %>%
filter(any(Action == "hire")) %>%
mutate(time_spent = difftime(date, date[Action == "hire"], units = "days")) %>%
right_join(d)
Данные
d <- structure(list(Id = c(101, 101, 101, 101, 103, 103, 103), Action = c("hire",
"terminate", "promoted", "promoted", "hire", "promoted", "terminate"
), date = c("02/22/2017", "12/11/2020", "11/11/2018", "03/22/2019",
"02/23/2016", "01/12/2018", "03/21/2019")), class = "data.frame", row.names = c(NA,
-7L))
Комментарии:
1. Спасибо, Бен, у меня есть одно сомнение, допустим, у нас есть еще один ID- 104, и у нас нет действия «нанять», но у нас есть другие действия — завершить, повысить, тогда это выдаст ошибку: «произошла ошибка в группе: Id = 104, как мы можем справиться с этой ситуацией’
2. @Nishant Смотрите отредактированный ответ. Вы можете добавить
filter
только к includeId
, у которого есть «hire» где-то в строке. Затем соедините данные. Сначала убедитесь, чтоdate
он находится в правильном формате. Надеюсь, это поможет!