Share |

пятница, 2 февраля 2018 г.

Свои функции в R, оптимизация препроцессинга подготовки данных в R



Я не работаю с макросами в excel - мозгов не хватает, но мне кажется, что то, что я покажу, есть эти самые макросы в R.
В R в подготовке модели очень много места занимают коды препроцессинга, подготовки данных. Меня лично убивают многокилометровые портянки. Понятно, что их не надо писать каждый раз заново, можно из предыдущих кодов вставлять, но сам факт копирования, вставки, потом этот код при каждом повторе кода заново запускать - не комильфо.
Хочу поделиться тем, как можно все это сократить. И сделаю это на примере кейса по текучести персонала используя первый специализированный пакет в R по HR аналитике.

И заодно рекламирую свой семинар по HR-аналитике в R - Семинар-практикум "HR-Аналитика в R", Москва, 23-24 апреля

Задача.

При решении задачи по текучести персонала мы всегда имеем колонки Дата приема и Дата увольнения, а нам надо получить из них переменные "Stag" и "Event". Это достаточно однообразная операция, она занимает на так много места, но тем не менее я у себя оптимизирую эту операцию.

Решение

Загружаем пакет 'HRanalytics'. Как установить пакет см. пост Пакет R HR analytics для HR аналитиков.

library(HRanalytics)
data("survey")
str(survey)
Эти данные - данные нашего исследования факторов текучести персонала (поучаствуйте, ау).
В этом исследовании респонденты описывают одно из своих мест работы от даты приема до даты увольнения. Мы можем построить модель прогноза текучести на основе регрессии Кокса, но сначала нам надо преобразовать дату приема и дату увольнения в стаж и события.
Создаем два скрипта в Rstudio: один основной, на котором мы будем решать задачу, а на второй вынесем формулы препроцессинга, подготовки данных. Этот второй скрипт можно будет впоследствии использовать много раз для решения подобных задач. У меня этот файл называется незамысловато: podgotovka.
В этом аподготовительном скрипте в R я прописываю формулу

stag = function(end, date_report, begin) {
  library(lubridate)
  x = ifelse(is.na(end), 0, 1)
  end = parse_date_time(end, c("dmy", "dmy_HMS")) 
  end[is.na(end)] =  as.Date(date_report, "%d.%m.%Y")  
  
  begin = parse_date_time(begin, c("dmy", "dmy_HMS"))
  y = as.numeric((end-begin)/(30.4375*24*60*60)) 
  
  return(data.frame('event' = x, 'stag'=y))
}
Эта функция позволяет нам создавать переменные стажа и события. Прокомментирую:

  1. на всякий случай я подгружаю пакет lubridate, если забываю подгрузить в основном скрипте
  2. x = ifelse(is.na(end), 0, 1)- это формула создания переменной event
  3. Далее - и вот здесь вам надо быть внимательными- идет формат работы с датами, который зависит от того, в каком формате данные подгружаются. Я здесь предусмотрел два формата (я надеюсь, вы понимаете по формуле).
  4. И в стаже у нас удивительный знаменатель - это от того, что формат даты у нас в секундах, и чтобы получить месяца, я делю на секунды.
  5. И функция возвращает датафрейм из двух переменных

Далее вы можете получить на данных исследования:

st = stag(survey$Дата.увольнения, survey$Отметка.времени, survey$Дата.трудоустройства) 
summary(st)
event             stag         
 Min.   :0.0000   Min.   :-130.037  
 1st Qu.:0.0000   1st Qu.:   5.979  
 Median :1.0000   Median :  19.959  
 Mean   :0.6061   Mean   :  35.370  
 3rd Qu.:1.0000   3rd Qu.:  47.359  
 Max.   :1.0000   Max.   : 591.146  
                  NA's   :80
И сразу получаем первый втык: какого хрена у нас стаж отрицательный? и почему в стаже таки 80 пустых значений? Ну это уже другая задачка.
Вы можете получить переменные так:

survey$stag = stag(survey$Дата.увольнения, survey$Отметка.времени, survey$Дата.трудоустройства)$stag
Переменную 'event' получите сами.
Когда вы будете работать со своими данными, то у вас дата выгрузки будет фиксированной, а не отдельной колонкой, поэтому вы пишите так

stag(q$Дата.увольнения, "20.12.2017", q$Дата.приема)
ВАЖНО: дату используете свою, эта произвольная
Ну т.е. если вам по барабану мой пакет, но у вас есть свои задачи, что вы просто берете эту формулу и работаете с ней.
Я хотел вставить эту формулу в пакет HRanalytics, но откровенно боюсь того, что пойдут баги типа: а если в Дате увольнения пустые значения не Nan, а "" или " "? Наверное, все эти ситуации можно предусмотреть, но я не готов так глубоко залезать.


Проще

Если у вас названия колонок уже давно определены (выгрузка из системы), данные вы выгружаете в одном формате, то можно сделать совсем просто


stag = function(q) {
  
q$event = 1
q$event[is.na(q$Дата.увольнения)] = 0
q$end = q$Дата.увольнения
q$end = dmy(q$end) # dmy это day-month-year
q$end[is.na(q$end)] =  "2017-12-20 UTC" # заполяем датой выгрузки отчета 
q$begin = dmy(q$Дата.приема)
q$stag = as.numeric((q$end-q$begin)/30.4375) 
return(q)}

Здесь вы видите, что уже заточено на конкретные данные. Но просто в том, что вы потом в основном скрипте просто пишите:
df = stag(df)
И у вас добавляются колонки стажа и евента.
ПыСы. Честно говоря, не уверен, что все гладко сделал, поэтому, если заметите ошибки, пишите.


__________________________________________________________
На этом все, читайте нас в фейсбукетелеграмме и вконтакте



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

Отправить комментарий

Популярные сообщения

п