【发布时间】:2018-08-22 22:40:05
【问题描述】:
使用下面的 for 循环,我可以创建给定员工上方所有经理的列表(本质上是员工经理、她经理的经理等的列表)
library(dplyr)
library(tidyr)
library(purrr)
# Create test data
ds <-
tibble(
emp_id = c("001", "002", "003", "004", "005"),
mgr_id = c("002", "004", "004", "005", NA)
)
# Hardcoded for-loop example
mgr_ids_above <- vector("list", length = 5)
id <- "001"
for (i in seq_along(mgr_ids_above)) {
mgr_ids_above[[i]] <- ds$mgr_id[ds$emp_id == id]
id <- mgr_ids_above[[i]]
}
# drop NAs
mgr_ids_above <- unlist(mgr_ids_above)
mgr_ids_above <- mgr_ids_above[!is.na(mgr_ids_above)]
# return to list format
as.list(mgr_ids_above)
我希望将此 for 循环应用于整个数据框并将结果保存在列表列中。我可以使用pmap() 成功地做到这一点,将硬编码的 for 循环应用于我的数据帧,但是当我尝试编写一个通用函数时,一切都崩溃了。
# Define custom function with hardcoded data and variable names
get_mgrs_above <- function(id, max_steps = 5){
mgr_ids_above <- vector("list", length = max_steps)
for (i in seq_along(mgr_ids_above)) {
mgr_ids_above[[i]] <- ds$mgr_id[ds$emp_id == id]
id <- mgr_ids_above[[i]]
}
# drop NAs
mgr_ids_above <- unlist(mgr_ids_above)
mgr_ids_above <- mgr_ids_above[!is.na(mgr_ids_above)]
# return to list format
as.list(mgr_ids_above)
}
# Apply custom function
ds_mgrs_above <-
ds %>%
mutate(
ranks_above = pmap(
list(id = emp_id),
get_mgrs_above
)
)
上面代码的输出是
A tibble: 5 x 3
emp_id mgr_id ranks_above
<chr> <chr> <list>
1 001 002 <list [3]>
2 002 004 <list [2]>
3 003 004 <list [2]>
4 004 005 <list [1]>
5 005 NA <list [0]>
ranks_above 列表列的内容看起来像
ds_mgrs_above$ranks_above[[1]]
[[1]]
[1] "002"
[[2]]
[1] "004"
[[3]]
[1] "005"
所有数据和变量作为参数提供的失败函数失败并显示消息“mutate_impl(.data, dots) 中的错误: 评估错误:元素 1 的长度为 2,而不是 1 或 5..”:
get_mgrs_above <- function(
data,
id = emp_id,
mgr_id = mgr_id,
emp_id = emp_id,
max_steps = 5){
mgr_ids_above <- vector("list", length = max_steps)
for (i in seq_along(mgr_ids_above)) {
mgr_ids_above[[i]] <- data$mgr_id[data$emp_id == id]
id <- mgr_ids_above[[i]]
}
# drop NAs
mgr_ids_above <- unlist(mgr_ids_above)
mgr_ids_above <- mgr_ids_above[!is.na(mgr_ids_above)]
# return to list format
as.list(mgr_ids_above)
}
ds %>%
mutate(
ranks_above = pmap(
list(
data = ds,
id = emp_id,
mgr_id = mgr_id,
emp_id = emp_id,
max_steps = 5
),
get_mgrs_above
)
)
为避免混淆,这篇文章是关于如何编写一个通用函数,该函数将从两列创建一个列表列。这是对拥有约 15,000 名员工的数据框进行更大规模数据整理尝试的一个组成部分。
【问题讨论】:
-
@CalumYou,是的,我已经更新了预期的输出示例。