R: реконструировать данные менеджера-сотрудника - PullRequest
0 голосов
/ 09 июня 2019

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

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

Вот код для создания образца набора данных.

employee_id = seq(1:10)
manager_id =c(1,1,2,3,4,2,3,1,4,5)

hr=data.frame(employee_id,manager_id)

Вот что я ожидаю: Используя employee_id 4 в качестве примера

employee_id managerL1 managerL2 managerL3
4           3         2         1

Я должен также упомянуть, что это упрощенный пример. В реальных данных, с которыми я работаю, идентификаторы менеджера и сотрудника не являются последовательными. Это несколько случайных чисел с префиксами. Сам идентификатор не имеет никакой информации на управленческом уровне. Уровень определяется исключительно данными.

Ответы [ 2 ]

2 голосов
/ 09 июня 2019

Похоже, это требует итеративного решения.

Начните с менеджеров наших сотрудников уровня 1.Индекс строки сотрудника, который является менеджером каждого сотрудника, равен

i <- 1
idx = match(hr$manager_id, hr$employee_id)

Менеджер менеджера равен hr$manager_id[idx], и мы можем использовать тот же самый подход match() итеративно.Записывайте и повторяйте до тех пор, пока в качестве менеджера не будет только одного сотрудника

repeat {
    idx = match(hr$manager_id[idx], hr$employee_id)
    hr[[paste0("manager_", i)]] = hr$employee_id[idx]
    if (length(unique(idx)) == 1)
        break
    i <- i + 1
}

В одном варианте можно предусмотреть одного или нескольких менеджеров высшего уровня, используя NA в качестве менеджера и соответствующим образом остановив

hr$employee_id[1] = NA  # the boss; there could be several top-level managers...
i <- 1
idx = match(hr$manager_id, hr$employee_id)
repeat {
    idx = match(hr$manager_id[idx], hr$employee_id)
    hr[[paste0("manager_", i)]] = hr$employee_id[idx]
    if (all(is.na(idx)))
        break
    i <- i + 1
}

1 голос
/ 09 июня 2019

Вот вариант с tidyverse

library(tidyverse)
hr %>%  
   uncount(manager_id, .remove = FALSE)  %>% 
   group_by(employee_id) %>% 
   mutate(new_id = row_number(), nm1 = str_c('manager_', new_id)) %>% 
   spread(nm1,new_id)
# A tibble: 10 x 7
# Groups:   employee_id [10]
#   employee_id manager_id manager_1 manager_2 manager_3 manager_4 manager_5
#         <int>      <dbl>     <int>     <int>     <int>     <int>     <int>
# 1           1          1         1        NA        NA        NA        NA
# 2           2          1         1        NA        NA        NA        NA
# 3           3          2         1         2        NA        NA        NA
# 4           4          3         1         2         3        NA        NA
# 5           5          4         1         2         3         4        NA
# 6           6          2         1         2        NA        NA        NA
# 7           7          3         1         2         3        NA        NA
# 8           8          1         1        NA        NA        NA        NA
# 9           9          4         1         2         3         4        NA
#10          10          5         1         2         3         4         5

или с map и spread

hr %>% 
   mutate(new_id = map(manager_id, seq)) %>% 
   unnest %>%
   mutate(nm1 = str_c('manager_', new_id)) %>% 
   spread(nm1, new_id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...