R:使用嵌套数据结构将不同长度的输入传递给purrr
我有两个列表R:使用嵌套数据结构将不同长度的输入传递给purrr,r,list,mapping,purrr,data-wrangling,R,List,Mapping,Purrr,Data Wrangling,我有两个列表foo和bar,其中length(foo)>length(bar)。我想对bar的每个元素应用函数length(bar)次,并将每个应用程序的输出存储在自己的列表中,将函数的所有应用程序存储在自己的列表中bar的每个元素中。这个嵌套列表输出结构很重要,因为我将它传递给需要嵌套列表的函数。我所拥有和想要的例子在最小的例子中 虽然嵌套for循环可以很好地实现这一点,但我一直在尝试使用purr的map函数来实现这一点。我通过创建一个length(bar)列表,其中每个元素都是foo,(b)
foo
和bar
,其中length(foo)>length(bar)
。我想对bar
的每个元素应用函数length(bar)
次,并将每个应用程序的输出存储在自己的列表中,将函数的所有应用程序存储在自己的列表中bar
的每个元素中。这个嵌套列表输出结构很重要,因为我将它传递给需要嵌套列表的函数。我所拥有和想要的例子在最小的例子中
虽然嵌套for循环可以很好地实现这一点,但我一直在尝试使用purr
的map
函数来实现这一点。我通过创建一个length(bar)
列表,其中每个元素都是foo
,(b)将这个新列表和bar
传递给purr::pmap()
中的匿名函数,然后(c)将它传递给purr:map()中的匿名函数
虽然这是可行的,但它似乎与purrr
的目的背道而驰:
- 我定义的是匿名函数,而不是
.x
、.y
和~
语法
- 我不是传递原始列表(长度不同),而是将一个列表转换为嵌套列表,以匹配另一个的长度。这可能是内存密集型、速度慢等
- 我使用的是嵌套列表,而不是更扁平的列表/数据帧,然后将它们划分到所需的数据结构中
在purrr
中是否有比我的aproach更适合处理不同长度列表的替代方法?如何修改我的代码(下面的最小示例)以更好地利用purr
的语法?一个想法()是使用cross()
或其他等效工具生成单个对象,以传递给pmap()
,但我不知道如何生成嵌套列表结构
library(purrr)
# Example data: 2 different-length lists
foo <- list(1, 2, 3)
bar <- list("df1", "df2")
# Desired output:
out <- list(list("df1_1", "df1_2", "df1_3"),
list("df2_1", "df2_2", "df2_3"))
# Distinctive features of output:
#length(out) == length(bar)
#length(out[[1]]) == length(out[[2]])
#length(out[[1]]) == length(foo)
# Can use purrr::pmap but this will concurrently
# iterate through each element of inputs ("in
# parallel") so need to create same-length inputs
foo_list <- rep(list(foo), 2)
# Pass our inputs to pmap then use map to iterate
# over foo contained in each foo_list element.
purrr::pmap(list(foo_list, bar),
function(foo, bar) {
map(foo, function(i) {
paste0(bar, "_", i)
})
})
库(purrr)
#示例数据:2个不同长度的列表
foo考虑使用嵌套的映射。在“条形图”列表上循环,然后在“foo”和粘贴上循环。这将返回一个嵌套的列表
,与OP的预期值相同
library(purrr)
out2 <- map(bar, ~ map(foo, function(y) paste0(.x, '_', y)))
identical(out, out2)
#[1] TRUE
或者使用base R
,我们可以使用outer
,创建字符串的矩阵
,然后按行(asplit
,其中边距
为1)拆分为向量
的列表,在列表
上循环,并将向量
的每个元素转换为具有as.list的列表
元素
out3 <- lapply(asplit(outer(bar, paste0('_', foo), FUN = paste0), 1), as.list)
identical(out, out3)
#[1] TRUE
out3您不能取消列表并更轻松地执行此操作。让我困惑的是.x是指foo
的元素还是bar
的元素。似乎有点含糊不清。@user3614648.x
总是返回当前调用的元素。当我们嵌套了多个调用时,最好使用传统的匿名函数,我们可以灵活地将其命名为x
或y
或任何其他名称来区分
out3 <- lapply(asplit(outer(bar, paste0('_', foo), FUN = paste0), 1), as.list)
identical(out, out3)
#[1] TRUE