0

I'm trying to make multiple ggplot charts from multiple data frames. I have developed the code below but the final loop doesn't work.

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]])
}

I know its something to do with

ll[[i]]

but I dont understand why because when I put that in the console it gives the dataframe I want. Also, is there a way do this the tidyverse way with the map functions instead of a for loop?

2 Answers 2

2

I assume you want to see two files called df1.png and df2.png at the end.

You need to somehow pass on the names of the dataframes to the function. One way of doing it would be through named list, passing the name along with the content of the list element.

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]))
}

In tidyverse you could just replace the loop with the following command without modifying the function.

purrr::walk2(ll, names(ll),chart_it)

or simply

purrr::iwalk(ll, chart_it)

There's also imap and lmap, but they will leave some output in the console, which is not what you would like to do, I guess.

Sign up to request clarification or add additional context in comments.

1 Comment

That's perfect. Thanks so much :)
0

The problem is in your chart_it function. It doesn't return a ggplot. Try saving the result of the pipe into a variable and return() that (or place it as the last statement in the function).

Something along the lines of

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)
}

2 Comments

Thanks for reply. If I run chart_it(df1) it saves the plot, so doesn't that mean my function is ok?
Tried the following chart_it <- function(x) { x %>% ggplot() + geom_line(mapping = aes(y=a,x=b)) + ggsave(paste0(substitute(x),".png")) -> chart return(chart) } And I get "Error: device must be NULL, a string or a function."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.