管道如何与 purrr map() 函数和“.”一起工作(点)符号

How do pipes work with purrr map() function and the "." (dot) symbol

同时使用管道和 purrr 的 map() 函数时,我对数据和变量的传递方式感到困惑。例如,这段代码按我的预期工作:

library(tidyverse)

cars %>% 
  select_if(is.numeric) %>% 
  map(~hist(.))

然而,当我尝试使用 ggplot 进行类似操作时,它的行为很奇怪。

cars %>% 
  select_if(is.numeric) %>% 
  map(~ggplot(cars, aes(.)) + geom_histogram())

我猜这是因为“.”在这种情况下,将一个向量传递给 aes(),它需要一个列名。无论哪种方式,我都希望我可以使用管道和 map() 将每个数字列传递给 ggplot 函数。提前致谢!

您不应该将原始数据传递给美学映射。相反,您应该动态构建 data.frame。例如

cars %>% 
  select_if(is.numeric) %>% 
  map(~ggplot(data_frame(x=.), aes(x)) + geom_histogram())
cars %>% 
  select_if(is.numeric) %>% 
  map2(., names(.), 
       ~{ggplot(data_frame(var = .x), aes(var)) + 
           geom_histogram() + 
           labs(x = .y)                    })

# Alternate version
cars %>% 
  select_if(is.numeric) %>% 
  imap(.,
       ~{ggplot(data_frame(var = .x), aes(var)) + 
           geom_histogram() + 
           labs(x = .y)                    })

还有一些额外的步骤。

  • 使用 map2 而不是 map。第一个参数是您传递给它的数据帧,第二个参数是该数据帧的 names 的向量,因此它知道要 map 的内容。 (或者,imap(x, ...)map2(x, names(x), ...) 的同义词。它是 "index-map",因此是 "imap"。)
  • 然后您需要显式封装数据,因为 ggplot 仅适用于数据帧和可强制对象。
  • 这也让您可以使用 .y 代词来命名地块。