当先前的 chan 不是正在循环的内容时,purrr 替代 Map

purrr alternative to Map when prior chan is not what is being looped over

我想了解有关 purrr 包的更多信息。我可以看到一些一致性的细节,但正在为任意问题的灵活性而苦苦挣扎。我一直喜欢 Map 的灵​​活性和相对易用性。我读过 pmap 但它似乎比 Map 更难处理,因为你想将一个对象传递给下一部分并让 n 个列表循环遍历该对象.

下面是一个最小的例子。该代码将 mtcars 传递到一个循环(在本例中为 Map),该循环依次遍历编写函数和文件扩展名,并使用先前链中的 mtcars 来写出一个文件。 我如何使用 purrr/tidyverse 方法编写此代码?

我很感激我可以简单地传递 c('fst', 'csv') 并使用 match.call 从单个向量构建扩展和编写函数。这个 MWE 是为了表明需要在一个沿着链传递的对象上传递 2 个或更多 lists/vectors(这个对象在某种意义上是静态的)。

library(tidyverse)
library(fst)

mtcars %>%
    {Map(function(fun, ext) {
            fun(., sprintf('mtcars.%s', ext))
        }, 
        list(fst::write_fst, readr::write_csv), 
        list('fst', 'csv')
    )} %>%
    invisible()

您可以使用 invoke_map 调用带有参数列表的函数列表,以及列表中所有函数共享的参数。

棘手的部分是正确嵌套路径列表,因为它需要是列表的列表。您可以在一行中完成所有这些,而不是先保存 funspaths;为了清楚起见,我这样做了。

library(tidyverse)

funs <- list(fst::write_fst, readr::write_csv)
paths <- map(list("fst", "csv"), ~list(path = sprintf("mtcars.%s", .)))

invoke_map(funs, paths, x = mtcars)

当它映射到这两个函数时,它们都将 mtcars 打印到控制台。不理想,但据我所知,walk 函数没有 invoke 版本,它使用副作用而不是返回数据框。这将保存文件 "mtcars.fst" 和 "mtcars.csv".