泛化for循环以在自定义函数中使用
使用下面的for循环,我可以创建一个给定员工之上所有经理的列表(基本上是一个员工的经理、她的经理的经理等的列表) 上述代码的输出是泛化for循环以在自定义函数中使用,r,for-loop,purrr,R,For Loop,Purrr,使用下面的for循环,我可以创建一个给定员工之上所有经理的列表(基本上是一个员工的经理、她的经理的经理等的列表) 上述代码的输出是 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]
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]>
我的函数失败,所有数据和变量都作为参数提供,失败的消息是“mutate_impl(.data,dots)中出错”:
计算错误:元素1的长度为2,而不是1或5..”:
get_mgrs_>。我想不出一种方法来调整您的代码,但我希望这种方法是有意义的。基本上,您希望从单个员工id表及其直接经理id表中获取每个员工的完整命令链。在这里,我创建该表查找
,并将其反复连接到输入数据框中,该输入数据框基本上就是员工id,一个命令链
列表列,我将每个额外的经理添加到其中,以及一个current\u join
列,该列存储在每次迭代中要查找的id
然后我们可以简单地将join_once
函数包装在join_all
中,该函数将一直调用它,直到到达所有命令链的末尾(只有NA
s)。我清理了输出以丢弃NAs,并将命令链打印为逗号分隔的字符串,这样您就可以看到它完成了什么
在某种程度上,我不知道这是否特别有效,因为您必须连接许多可能不需要的变量(例如,004
的连接次数比需要的多三次),但我认为这至少在概念上是简单的
库(tidyverse)
查找百分比
变异(命令链=emp\u id,当前连接=emp\u id)
加入你一次%
左联合(查找,按=c(“当前联合”=“emp\U id”))%>%
变异(
command_chain=map2(command_chain,mgr_id,~c(.x,.y)),
当前加入=管理者id
) %>%
选择(-mgr\u id)
}
连接所有emp id命令链抄送为字符串
#>
#> 1 001 001,002,004,005
#> 2 002 002,004,005
#> 3 003 003,004,005
#> 4 004 004,005
#> 5 005 005
由(v0.2.0)于2018年8月22日创建。您的循环结构让我感到困惑,因此我在时使用对其进行了更改。这只允许在最后应用map
get_mgrs_above <- function(id, data = NULL, max_steps = 5) {
stopifnot(!is.null(data))
mgr_ids_above <- list()
mgr <- id
iter <- 0
while (iter < max_steps & !is.na(mgr)) {
mgr <- data$mgr_id[data$emp_id == mgr]
if (!is.na(mgr)) {
mgr_ids_above <- append(mgr_ids_above, mgr)
}
iter <- iter + 1
}
return(mgr_ids_above)
}
ds$ranks_above <- map(ds$emp_id, get_mgrs_above, data = ds)
get_mgrs_over@CalumYou,是的,我已经更新了预期的输出示例。
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]>
ds_mgrs_above$ranks_above[[1]]
[[1]]
[1] "002"
[[2]]
[1] "004"
[[3]]
[1] "005"
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
)
)
get_mgrs_above <- function(id, data = NULL, max_steps = 5) {
stopifnot(!is.null(data))
mgr_ids_above <- list()
mgr <- id
iter <- 0
while (iter < max_steps & !is.na(mgr)) {
mgr <- data$mgr_id[data$emp_id == mgr]
if (!is.na(mgr)) {
mgr_ids_above <- append(mgr_ids_above, mgr)
}
iter <- iter + 1
}
return(mgr_ids_above)
}
ds$ranks_above <- map(ds$emp_id, get_mgrs_above, data = ds)