【问题标题】:Pipe list into purrr::map and use seq_along in .x管道列表进入 purrr::map 并在 .x 中使用 seq_along
【发布时间】:2019-02-14 11:17:16
【问题描述】:

我经常生成小标题列表,然后我希望将其转发到purrr::map 调用中。很多时候,我想为每个小标题添加一个标识符列,然后将它们连接在一起。我正在寻找一种方法,不必生成污染我的全局环境的中间变量,只是为了能够使用 seq_along 添加 id 列。

加载库:

library(tidyverse)

生成代表:

reprex_list <- list(Aleena = structure(list(
  name = "Ratts Tyerell", height = 79L,
  mass = 15, hair_color = "none", skin_color = "grey, blue",
  eye_color = "unknown", birth_year = NA_real_, gender = "male",
  homeworld = "Aleen Minor", films = list("The Phantom Menace"),
  vehicles = list(character(0)), starships = list(character(0))
), class = c(
  "tbl_df",
  "tbl", "data.frame"
), row.names = c(NA, -1L)), Besalisk = structure(list(
  name = "Dexter Jettster", height = 198L, mass = 102, hair_color = "none",
  skin_color = "brown", eye_color = "yellow", birth_year = NA_real_,
  gender = "male", homeworld = "Ojom", films = list("Attack of the Clones"),
  vehicles = list(character(0)), starships = list(character(0))
), class = c(
  "tbl_df",
  "tbl", "data.frame"
), row.names = c(NA, -1L)), Cerean = structure(list(
  name = "Ki-Adi-Mundi", height = 198L, mass = 82, hair_color = "white",
  skin_color = "pale", eye_color = "yellow", birth_year = 92,
  gender = "male", homeworld = "Cerea", films = list(c(
    "Attack of the Clones",
    "The Phantom Menace", "Revenge of the Sith"
  )), vehicles = list(
    character(0)
  ), starships = list(character(0))
), class = c(
  "tbl_df",
  "tbl", "data.frame"
), row.names = c(NA, -1L)))

从这里开始,我要做的是在我的全局环境中生成一个中间变量,然后再次启动 map,如下所示:

species_id <- names(reprex_list) # don't want to have to break the pipe and add this to my blobal environment
map(.x = seq_along(reprex_list), .f = ~reprex_list[[.x]] %>%
  dplyr::mutate(species = species_id[[.x]])) %>%
  map(.f = ~ .x %>% mutate_all(as.character)) %>%
  purrr::reduce(full_join) %>%
  type_convert()

愚蠢的是,我想要的是:

reprex_list %>% # Sometimes this is piped in from many previous lines of code so I don't want to have to assign this to a separate variable to be able to carry on.
  map(.x = seq_along(.), .f = ~ .[[.x]] %>% dplyr::mutate(species = names(.)[[.x]])) %>%
  map(.f = ~ .x %>% mutate_all(as.character)) %>%
  purrr::reduce(full_join) %>%
  type_convert()

但后者不起作用。现在显然这里的额外麻烦是最小的,但有时我在生成中间列表之前已经有多行代码,然后我必须将其分配给一个单独的变量。然后再次开始管道,我很确定可以在一个代码块中完成,但我还没有找到一种方法。有任何想法吗?谢谢。

【问题讨论】:

  • dplyr::bind_rows(reprex_list, .id = "species") %&gt;% tidyr::unnest(films) 接近你想要的吗?

标签: r dplyr pipe purrr


【解决方案1】:

尝试使用 purrr::map_dfr 并指定 .id 参数:

reprex_list %>% map_dfr(~mutate_all(., as.character), .id='species')

或者更好的是添加物种列而不做其他任何事情:

reprex_list %>% map_dfr(identity, .id='species')

编辑:

reprex_list %>% bind_rows(.id = "species")

实际上是最好的方法,根据上面的评论

【讨论】:

  • 很接近了...它取代了 purrr::reduce(full_join),这将解决大约 90% 的用例。问题更多的是是否可以在管道下游使用.x = seq_along()
  • 您可以使用imap - 我稍后会发布完整答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-25
  • 2018-06-17
  • 2021-08-01
  • 1970-01-01
相关资源
最近更新 更多