数据集的代码:
sample <- structure(list(`Employee ID` = c(200, 201, 202, 203, 204, 205
), `Leader1 Name` = c("CH", "CH", "CH", "CH", "CH", "CH"), `Leader1 Level` = c("Founder",
"Founder", "Founder", "Founder", "Founder", "Founder"), `Leader2 Name` = c("HF",
"SR", "HF", "HF", "AK", "UT"), `Leader2 Level` = c("CEO", "VP",
"CEO", "CEO", "Exec", "Exec"), `Leader3 Name` = c("KK", NA, "NA",
NA, "TR", NA), `Leader3 Level` = c("VP", NA, "VP", NA, "VP",
NA), `Leader4 Name` = c("EQ", NA, "YY", NA, NA, NA), `Leader4 Level` = c("Director",
NA, "VP", NA, NA, NA)), row.names = c(NA, -6L), class = c("tbl_df",
"tbl", "data.frame"))
我希望获得每位员工在每个层次结构中的领导者姓名。所以我期望的输出是这样的:
我的处理方法是使用定界符将所有领导者的姓名和级别连接起来,然后去除每个级别
sample$AllLevels <- paste(sample$`Leader1 Name`, sample$`Leader1 Level`,
sample$`Leader2 Name`, sample$`Leader2 Level`,
sample$`Leader3 Name`, sample$`Leader3 Level`,
sample$`Leader4 Name`, sample$`Leader4 Level`,
sep = "~~")
sample$DirectorLevel <- unlist(lapply(strsplit(sample$AllLevels, "Director", fixed = TRUE), '[', 1))
sample$VPLevel <- unlist(lapply(strsplit(sample$DirectorLevel, "VP", fixed = TRUE), '[', 1))
sample$ExecLevel <- unlist(lapply(strsplit(sample$VPLevel, "Exec", fixed = TRUE), '[', 1))
sample$CEOLevel <- unlist(lapply(strsplit(sample$ExecLevel, "CEO", fixed = TRUE), '[', 1))
sample$FounderLevel <- unlist(lapply(strsplit(sample$CEOLevel, "Founder", fixed = TRUE), '[', 1))
sample$Director <- unlist(lapply(strsplit(sample$DirectorLevel, "~~", fixed = TRUE), tail, 1))
sample$VP <- unlist(lapply(strsplit(sample$VPLevel, "~~", fixed = TRUE), tail, 1))
sample$Exec <- unlist(lapply(strsplit(sample$ExecLevel, "~~", fixed = TRUE), tail, 1))
sample$CEO <- unlist(lapply(strsplit(sample$CEOLevel, "~~", fixed = TRUE), tail, 1))
sample$Founder <- unlist(lapply(strsplit(sample$FounderLevel, "~~", fixed = TRUE), tail, 1))
sample <- sample[,c(1, 16:20)]
这种方法的问题是,如果在特定级别之间没有领导者,那么我将接替下一个领导者,而不是NA。有关员工ID 200,请参见第1行。在执行级别中也重复了VP“ KK”。其他行也有相同的问题。
是否有更好的方法来获得所需的结果?
答案 0 :(得分:1)
这是tidyverse
的一个选项(pivot_longer
来自tidyr
的开发者-安装here的信息),我们将数据重塑为“长”格式(pivot_longer
,然后spread
将其预处理后恢复为“宽”格式
library(dplyr)
library(tidyr)# ‘0.8.3.9000’
library(stringr)
lvls <- c("Director", "VP", "Exec", "CEO", "Founder")
sample %>%
rename_at(-1, ~ str_replace(., "(\\S+) (\\S+)", '\\2_\\1')) %>%
pivot_longer(-`Employee ID`, names_to = c(".value", "group"), names_sep = '_') %>%
na.omit %>%
select(-group) %>%
group_by(`Employee ID`,
Level = factor(Level,
levels = lvls))%>%
mutate(rn = row_number()) %>%
spread(Level, Name) %>%
select(-rn)
# A tibble: 7 x 6
# Groups: Employee ID [6]
# `Employee ID` Director VP Exec CEO Founder
# <dbl> <chr> <chr> <chr> <chr> <chr>
#1 200 EQ KK <NA> HF CH
#2 201 <NA> SR <NA> <NA> CH
#3 202 <NA> NA <NA> HF CH
#4 202 <NA> YY <NA> <NA> <NA>
#5 203 <NA> <NA> <NA> HF CH
#6 204 <NA> TR AK <NA> CH
#7 205 <NA> <NA> UT <NA> CH
注意:修正了操作输出中提到的重复步骤
或使用melt/dcast
中的data.table
library(data.table)
dcast(melt(setDT(sample), measure = patterns("Level", "Name"),
na.rm = TRUE)[, value1 := factor(value1,
levels = lvls)],
`Employee ID` + rowid(`Employee ID`, value1) ~ value1,
value.name = 'value2')[, `Employee ID_1` := NULL][]
#. Employee ID Director VP Exec CEO Founder
#1: 200 EQ KK <NA> HF CH
#2: 201 <NA> SR <NA> <NA> CH
#3: 202 <NA> NA <NA> HF CH
#4: 202 <NA> YY <NA> <NA> <NA>
#5: 203 <NA> <NA> <NA> HF CH
#6: 204 <NA> TR AK <NA> CH
#7: 205 <NA> <NA> UT <NA> CH