Функция R для определения предыдущего значения - PullRequest
0 голосов
/ 06 июля 2019

Я пытаюсь составить таблицу сотрудников, которым они отчитываются и на каком уровне.

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

Моя таблица сотрудников выглядит так:

input = structure(list(Level.1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L), .Label = "Board", class = "factor"), Level.2 = structure(c(2L, 
2L, 2L, 1L, 1L, 3L, 3L), .Label = c("Aasha", "Grace", "Marisol"
), class = "factor"), Level.3 = structure(c(4L, 4L, 3L, 1L, 1L, 
2L, 2L), .Label = c("Alex", "Chandler", "Millie", "Tushad"), class = "factor"), 
    Level.4 = structure(c(2L, 2L, 6L, 1L, 5L, 3L, 4L), .Label = c("#", 
    "Frank", "Joey", "Rachel", "Sarah", "Tony"), class = "factor"), 
    Level.5 = structure(c(3L, 2L, 1L, 1L, 1L, 4L, 1L), .Label = c("#", 
    "Lela", "Millie", "Ross"), class = "factor"), Level.6 = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L), .Label = "#", class = "factor")), class = "data.frame", row.names = c(NA, 
-7L))

и используя технику, описанную здесь Ронаком (stackoverflow.com/questions/56903188/create-a-table-from-a-hierarchy/) что,

as.data.frame(t(apply(input, 1, function(x) 
       {new_x = x[x != "###"]; c(rev(tail(new_x, 2)), length(new_x)) })))

Я могу получить большую часть необходимой таблицы. Но у меня возникают проблемы при попытке получить «начальников» (например, тех, у кого есть работники, но они не «совет»).

Мой идеальный вывод выглядел бы примерно так (я добавил имена для облегчения понимания):

structure(list(Subordinate = structure(c(9L, 4L, 14L, 5L, 7L, 
13L, 9L, 2L, 1L, 12L, 11L, 6L, 3L, 8L, 10L), .Label = c("Aasha", 
"Alex", "Chandler", "Frank", "Grace", "Joey", "Lela", "Marisol", 
"Millie", "Rachel", "Ross", "Sarah", "Tony", "Tushad"), class = "factor"), 
    Boss = structure(c(5L, 10L, 6L, 3L, 5L, 9L, 6L, 1L, 3L, 2L, 
    7L, 4L, 8L, 3L, 4L), .Label = c("Aasha", "Alex", "Board", 
    "Chandler", "Frank", "Grace", "Joey", "Marisol", "Millie", 
    "Tushad"), class = "factor"), Level = c(5L, 4L, 3L, 2L, 5L, 
    4L, 3L, 3L, 2L, 4L, 5L, 4L, 3L, 2L, 4L)), class = "data.frame", row.names = c(NA, 
-15L))

Я думаю, что, возможно, я делаю это с помощью цикла, но это не самый лучший ответ. Кто-нибудь может предложить какие-либо другие советы?

1 Ответ

1 голос
/ 06 июля 2019

Не удалось придумать более красивое решение, но это работает. Используя while цикл в вызове apply, использованном ранее, мы можем сделать

output <- do.call(rbind.data.frame, apply(input, 1, function(x) {
   new_x = as.character(x[x != "#"])
   list_df <- list()
   i = 1
   while(length(new_x) >= 2) {
      #Get last 2 eneteries
      list_df[[i]] <- c(rev(tail(new_x, 2)), length(new_x))
      #Go one level deeper
      new_x = head(new_x, -1)
      i  = i +1
   }
   do.call(rbind, list_df)
}))

#To remove duplicate enteries
output[!duplicated(output), ]

#         V1       V2 V3
#1    Millie    Frank  5
#2     Frank   Tushad  4
#3    Tushad    Grace  3
#4     Grace    Board  2
#5      Lela    Frank  5
#9      Tony   Millie  4
#10   Millie    Grace  3
#12     Alex    Aasha  3
#13    Aasha    Board  2
#14    Sarah     Alex  4
#17     Ross     Joey  5
#18     Joey Chandler  4
#19 Chandler  Marisol  3
#20  Marisol    Board  2
#21   Rachel Chandler  4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...