jimbo
jimbo

Reputation: 176

Sending dataframes within list to a plot function

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?

Upvotes: 0

Views: 76

Answers (2)

dmi3kno
dmi3kno

Reputation: 3055

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.

Upvotes: 2

Roman Luštrik
Roman Luštrik

Reputation: 70653

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

Upvotes: 0

Related Questions