有没有办法在purrr / lapply中自我识别列表元素的名称?

时间:2019-05-14 22:35:54

标签: r purrr

我想在lapply()map()函数中提取列表元素的名称作为绘图标题的文本。

关键是要在lapply或map调用中自识别列表元素的名称,而不是将其作为附加参数提供。我的实际用例已经在函数中加入了其他参数,我很好奇是否有办法做到这一点,因为它将大大简化事情。

自我标识purrr :: map或lapply中的列表元素 说我有一个清单

library(tidyverse)
my_list <- list(A = data.frame(level = factor(1:5),
                               value = rnorm(5)),
                B = data.frame(level = factor(1:5),
                               value = rnorm(5)))

和一个简单的函数来绘制它

test_fun <- function(named_list) {
  ggplot(named_list) +
    geom_col(aes(level, value)) +
    ggtitle(named_list)
}

我想做这样的事情:

purrr::map(my_list, test_fun) 

...但是将它们命名为“ A”和“ B”。

目标是在map / lapply中标识元素“ A”或“ B”的名称 这样,我可以将该名称作为情节标题传递,而不必将其作为另一个函数参数提供。

我已经在函数中尝试过这些:

names(named_list)
# &
attr(named_list, "name")

但是它们每个都会在元素A或B中拉出名称,这不是期望的行为。我想升一级。

我知道我可以使用map2将名称作为一个单独的对象传递

my_names <- names(my_list)
test_fun2 <- function(named_list, my_names) {
  ggplot(named_list) +
    geom_col(aes(level, value)) +
    ggtitle(my_names)
}

然后执行以下操作:

map2(my_list, my_names, test_fun2)

但是有没有办法只是插入列表元素名称而不是这样做呢?如果还不行,我很好奇是否存在某种方式,或者是否坚持提供名称。

编辑:寻找关于imap()的答案的答案:

我可以通过简单的示例获得imap()的建议,但是只能使用匿名函数。如果我能对下面的示例有所了解,那么我应该可以扩展到更复杂的用法。

为什么会失败

test_fun_imap <- function(named_list) {
  ggplot(.x) +
    geom_col(aes(level, value)) +
    ggtitle(.y)
}

imap(my_list, test_fun_imap)

但这可行

imap(my_list, ~{
  ggplot(.x) +
    geom_col(aes(level, value)) +
    ggtitle(.y)
}
)

1 个答案:

答案 0 :(得分:3)

正如@joran所提到的,您可以使用imap,但是为此您需要将两个参数传递给该函数才能起作用

test_fun_imap <- function(x, y) {
   ggplot(x) +
    geom_col(aes(level, value)) +
    ggtitle(y)
}

然后您可以致电

purr::imap(my_list, test_fun_imap)

只要知道为什么它不适用于maplapply,您可以通过在函数中添加browser()来调试该函数

test_fun <- function(named_list) {
   browser()
  ggplot(named_list) +
    geom_col(aes(level, value)) +
    ggtitle(named_list)
}

现在,使用map

对其进行调用
purrr::map(my_list, test_fun)  

检查作为参数named_list传递的内容

Called from: .f(.x[[i]], ...)
Browse[1]> named_list
#  level    value
#1     1 -1.20707
#2     2  0.27743
#3     3  1.08444
#4     4 -2.34570
#5     5  0.42912

您看到数据帧已传递,并且没有该列表名称("A")的信息,因此,无法将其用作图的标题。如您所知,您可以单独使用map2mapply传递列表名称。