Поиск текучести кадров по отделам в R - PullRequest
1 голос
/ 20 марта 2019

Я ищу текучесть кадров каждым отделом в месяц.Мои данные состоят из идентификатора сотрудника, даты найма, отдела, даты увольнения и HR_Status.

enter image description here

Я хочу найти оборот по месяцам по дивизионам.

Leavers = Счетчик текущего месяца, взятый из TermDate

Оборот за определенный месяц = ​​Leavers текущего месяца / AVG (Количество строк за последний месяц и текущий месяц)

Ранее я задавал этот вопрос, и кто-то ответил на него здесь, но это было не по группе Отдела.

Поиск месяца по обороту за месяц

Воспроизвести

structure(list(TerminationDate = structure(c(16921, 16921, 12814, 
13028, 15392, 15160, 15186, NA, 17135, 12788, 14491, NA, 15166, 
15126, 15113, 17060, 13283, 12916, NA, 17905, 15611, 17135, 13299, 
17183, 17256, 12761, 17256, 17256, 14421, 14526, 12892, 17214, 
14526, 14526, 15160, 12863, 12726, 14491, 13010, 16073, 16073, 
13955, 15125, 15317, NA, 15429, 15474, 12843, 15237, 12921), class = "Date"), 
    HireDate = structure(c(759283200, 759283200, 766281600, 773020800, 
    781056000, 781056000, 783216000, 786240000, 787708800, 792201600, 
    792547200, 790732800, 796694400, 802828800, 813715200, 764985600, 
    828316800, 846374400, 848188800, 848361600, 848793600, 850003200, 
    861580800, 867715200, 870134400, 873072000, 875664000, 875664000, 
    876182400, 876700800, 878342400, 878342400, 878515200, 879120000, 
    879724800, 881193600, 881539200, 883612800, 883612800, 883612800, 
    883612800, 883612800, 883612800, 883612800, 883612800, 888710400, 
    888710400, 890697600, 893030400, 893376000), class = c("POSIXct", 
    "POSIXt"), tzone = "UTC"), HrstatusName = c("Resigned", "Resigned", 
    "Resigned", "Resigned", "Resigned", "Resigned", "Resigned", 
    "Regular", "Resigned", "Resigned", "Resigned", "Regular", 
    "Gross Misconduct", "Resigned", "Resigned", "Deceased", "Resigned", 
    "Resigned", "Regular", "Terminated", "Resigned", "Resigned", 
    "Resigned", "Resigned", "Resigned", "Resigned", "Resigned", 
    "Resigned", "Resigned", "Resigned", "Resigned", "Resigned", 
    "Resigned", "Resigned", "Resigned", "Resigned", "Resigned", 
    "Resigned", "Resigned", "Terminated", "Terminated", "Terminated", 
    "Retired", "Resigned", "Regular", "Resigned", "Resigned", 
    "Resigned", "Resigned", "Resigned"), EmployeeId = c("39bab084", 
    "39bab084", "5664d681", "520d0890", "20d65e2d", "eb8a8d88", 
    "1d30178f", "6dec15c8", "f67d57de", "76fb57f8", "3b33f6f3", 
    "a0a2b4e5", "9aa8d595", "dc820f73", "acace7da", "740ee9ec", 
    "35c81bd8", "f075debf", "5602d50b", "0d2d3f55", "5de0aee6", 
    "30cb76f7", "a9af8af5", "a95d601b", "32cc220d", "c476b80a", 
    "90772765", "90772765", "9c79745a", "ec579cf3", "f152ac4b", 
    "00041e9e", "b261e06b", "0efff3b5", "44db7a6c", "63d42ba4", 
    "38fbc1fa", "9960e29c", "48d52953", "051d8858", "051d8858", 
    "f44b3a8d", "3f17e928", "250c1bac", "68c4baa7", "7c3e5ee1", 
    "e7af1cf7", "cb4236d2", "f85f925b", "432da957"), Division = c("a60c5c5c", 
    "a60c5c5c", "3cc0c23b", "7e23b2d7", "3cc0c23b", "3cc0c23b", 
    "3cc0c23b", "eae5d36f", "c3abc225", "3cc0c23b", "7e23b2d7", 
    "eae5d36f", "3cc0c23b", "7e23b2d7", "eae5d36f", "a60c5c5c", 
    "7e23b2d7", "3cc0c23b", "3cc0c23b", "3cc0c23b", "c3abc225", 
    "c3abc225", "c3abc225", "5d980f59", "c3abc225", "eae5d36f", 
    "c3abc225", "c3abc225", "3cc0c23b", "a60c5c5c", "c3abc225", 
    "eae5d36f", "7e23b2d7", "a60c5c5c", "3cc0c23b", "3cc0c23b", 
    "3cc0c23b", "7e23b2d7", "3cc0c23b", "7e23b2d7", "7e23b2d7", 
    "7e23b2d7", "7e23b2d7", "3cc0c23b", "eae5d36f", "c3abc225", 
    "3cc0c23b", "216743cf", "3cc0c23b", "3cc0c23b")), class = c("data.table", 
"data.frame"), row.names = c(NA, -50L), .internal.selfref = <pointer: 0x0000000006261ef0>)

Пробный код

library(data.table)

df_leavers <- setDT(df)[, `:=` (TermDate = as.Date(as.character(TermDate)),
                                HireDate = as.Date(as.character(HireDate)))]

df_presences <- copy(df_leavers)

df_leavers <- df_leavers[, TermDate := format(TermDate, "%Y-%m")][!is.na(TermDate), (Leavers = .N), , by = TermDate]

df_presences <- df_presences[, maxTerm := max(TermDate, na.rm = T)][
  is.na(TermDate), TermDate := maxTerm][
    , .(YearMonth = format(seq(HireDate, TermDate, by = "month"), "%Y-%m")), by = 1:nrow(df)][
      , (Presences = .N), by = YearMonth]

df_final <- df_leavers[df_presences, on = .(TermDate = YearMonth)]

setnames(df_final, c("YearMonth", "Leavers", "Presences"))

df_final <- df_final[is.na(Leavers), Leavers := 0][order(YearMonth),][, previousMonth := shift(Presences)][
  is.na(previousMonth), previousMonth := 0][, AvgPresences := (Presences + previousMonth) / 2][
    , Turnover := round(Leavers / AvgPresences, 2)][, "previousMonth" := NULL]

Это дает мне вывод правильно, за исключением того, что не делится на деление

Желаемый выход

Date         Turnover  Division
2019-01      0.23      XYC
2019-01      0.02      ZYV

1 Ответ

1 голос
/ 20 марта 2019

Я не уверен, что это то, что вам нужно.

Я сделал несколько дополнительных столбцов, чтобы вы могли понять каждый шаг.

library(dplyr)
library(zoo) 

df %>%
  mutate(month = as.yearmon(TerminationDate, "%y/%m")) %>%
   group_by(month, Division) %>% 
    tally(name = "leavers") %>% 
      group_by(Division) %>%
       mutate(prevmonth = lag(leavers, order_by = month),
              sum = leavers + prevmonth, 
              turnover = leavers/(sum/2)) %>%
          select(Division, month, leavers, sum, prevmonth, turnover) %>%
            arrange(Division, month)

# A tibble: 36 x 6
# Groups:   Division [7]
   Division month         leavers   sum prevmonth turnover
   <chr>    <S3: yearmon>   <int> <int>     <int>    <dbl>
 1 216743cf Mrz 2005            1    NA        NA   NA    
 2 3cc0c23b Nov 2004            1    NA        NA   NA    
 3 3cc0c23b Jan 2005            2     3         1    1.33 
 4 3cc0c23b Mrz 2005            1     3         2    0.667
 5 3cc0c23b Mai 2005            2     3         1    1.33 
 6 3cc0c23b Aug 2005            1     3         2    0.667
 7 3cc0c23b Jun 2009            1     2         1    1    
 8 3cc0c23b Jul 2011            4     5         1    1.6  
 9 3cc0c23b Sep 2011            1     5         4    0.4  
10 3cc0c23b Dez 2011            1     2         1    1    
# ... with 26 more rows

Итак, я сделал для 3cc0c23b в январе 2005 года:

enter image description here.

Кажется, что вам подходит объяснение

Оборот за определенный месяц = ​​текущие месяцы / AVG (количество строк за последний месяц и текущий месяц)

Но особенно часть «предыдущий месяц» требует дополнительной информации.Вы имеете в виду предыдущий месяц в своем наборе данных?Потому что есть много месяцев без данных.Мое решение учитывает последний месяц в вашем наборе данных.Таким образом, оборот первого месяца в каждом подразделении, а также в подразделении с одним месяцем, имеют NA в качестве оборота.

Если вы имеете в виду предыдущий месяц в календаре, а его отсутствие в наборе данных означает отсутствие выпускников в этом месяце, укажите, пожалуйста.

ОБНОВЛЕНИЕ: Это странно .. В документации CRAN для dplyr

https://cran.r -project.org / web / packages / dplyr / dplyr.pdf

tally() и count() имеют аргументname = чтобы присвоить имя новому столбцу, который мне подходит.

Но здесь: https://www.rdocumentation.org/packages/dplyr/versions/0.7.8/topics/tally

там написано:

В настоящее время нет способа контролировать имя выходной переменной - если вам нужно изменить значение по умолчанию,Вы должны будете написать резюме () самостоятельно.

И это не работает для вас.Это проблема версии?Я использую dplyr_0.8.0.1

Но хорошо, тогда давайте сделаем это:

df %>%
  mutate(month = as.yearmon(TerminationDate, "%y/%m")) %>%
  group_by(month, Division) %>%
  summarise(leavers = n()) %>% 
  group_by(Division) %>%
  mutate(prevmonth = lag(leavers, order_by = month),
         sum = leavers + prevmonth, 
         turnover = leavers/(sum/2)) %>%
  select(Division, month, leavers, sum, prevmonth, turnover) %>%
  arrange(Division, month)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...