我试图从多个数据框制作多个ggplot图表。我已经开发了下面的代码,但最后一个循环不起作用。
df1 <- tibble(
a = rnorm(10),
b = rnorm(10)
)
df2 <- tibble(
a = rnorm(20),
b = rnorm(20)
)
chart_it <- function(x) {
x %>% ggplot() +
geom_line(mapping = aes(y=a,x=b)) +
ggsave(paste0(substitute(x),".png"))
}
ll <- list(df1,df2)
for (i in seq_along(ll)) {
chart_it(ll[[i]])
}
我知道它与
有关ll[[i]]
但我不明白为什么,因为当我把它放在控制台时,它会提供我想要的数据帧。另外,有没有办法使用map函数而不是for循环来实现tidyverse方式呢?
答案 0 :(得分:2)
我假设您希望最后看到两个名为df1.png
和df2.png
的文件。
您需要以某种方式将数据帧的名称传递给该函数。一种方法是通过命名列表,将名称与列表元素的内容一起传递。
library(ggplot2)
library(purrr)
df1 <- tibble(
a = rnorm(10),
b = rnorm(10)
)
df2 <- tibble(
a = rnorm(20),
b = rnorm(20)
)
chart_it <- function(x, nm) {
p <- x %>% ggplot() +
geom_line(mapping = aes(y=a,x=b))
ggsave(paste0(nm,".png"), p, device = "png")
}
ll <- list(df1=df1,df2=df2)
for (i in seq_along(ll)) {
chart_it(ll[[i]], names(ll[i]))
}
在tidyverse中,您可以使用以下命令替换循环而无需修改函数。
purrr::walk2(ll, names(ll),chart_it)
或只是
purrr::iwalk(ll, chart_it)
还有imap
和lmap
,但他们会在控制台中留下一些输出,我想这不是你想做的。
答案 1 :(得分:0)
问题出在您的chart_it
功能中。它没有返回ggplot
。尝试将管道的结果保存到变量return()
中(或将其作为函数中的最后一个语句)。
的内容
chart_it <- function(x) {
chart <- x %>% ggplot() +
geom_line(mapping = aes(y=a,x=b))
ggsave(paste0(substitute(x),".png")) # this will save the last ggplot figure
return(chart)
}