Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
泛化for循环以在自定义函数中使用_R_For Loop_Purrr - Fatal编程技术网

泛化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]

使用下面的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]> 
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)