0

I've leaned heavily on a couple other SO posts already, but can't seem to get past this one. Here are the references i've used:

Loop with a defined ggplot function over multiple dataframes

Loop in R to create and save series of ggplot2 plots with specified names

My goal is to use a loop to save each pie plot from the list of dataframes: "Sample_List" (which will be much longer). I keep getting this error though, and am stumped:

"Error: Aesthetics must be either length 1 or the same as the data (1): fill, y"

Data:

DZmix_SC1:

# A tibble: 3 × 4
  Sample_ID Potential_Sources Relative_Contribution Metric
  <chr>     <chr>                             <dbl> <chr> 
1 SC1_18    Uintas                                0 KV    
2 SC1_18    Sierra Madre                         22 KV    
3 SC1_18    CMB                                  78 KV 

DZmix_5_SC:

# A tibble: 3 × 4
  Sample_ID Potential_Sources Relative_Contribution Metric
  <chr>     <chr>                             <dbl> <chr> 
1 5-SC_18   Uintas                                0 KV    
2 5-SC_18   Sierra Madre                         29 KV    
3 5-SC_18   CMB                                  71 KV 

DZmix_PL3:

# A tibble: 3 × 4
  Sample_ID Potential_Sources Relative_Contribution Metric
  <chr>     <chr>                             <dbl> <chr> 
1 PL3_18    Uintas                               69 KV    
2 PL3_18    Sierra Madre                          0 KV    
3 PL3_18    CMB                                  31 KV   

Here's what i have so far:

Sample_list <- c("DZmix_SC1", "DZmix_5_SC", "DZmix_PL3")

DZpie.fn <- function(df,title) {
  df <- df  %>% 
  mutate(Relative_Contribution = round(Relative_Contribution,1)) %>%
  arrange(desc(Potential_Sources))
ggpie(df,"Relative_Contribution", label = "Relative_Contribution",
      fill = "Potential_Sources", color = "white", size = 1.5,
      palette = c("#636363", "#cccccc", "#969696")) +
      lab.pos = c("in"),
      lab.font = c(0, "bold", "black")) +
  theme(legend.position = "none", 
        panel.background = element_rect(fill = "transparent"), 
        plot.background = element_rect(fill = "transparent", color = NA)) 
} #end DZpie.fn

for(i in Sample_list){
  print(DZpie.fn(get(i), i)) 
}

And ultimately i'd like to replace the print function in the loop with a ggsave function that works... heres my effort:

ggsave(DZpie.fn, filename=paste("/outputpath/",i,".png",sep=""))

Thanks in advance for the help!!

ecp.55
  • 15
  • 4
  • This error is related to `fill` parameter of ggpie. Try to change it to `fill = Potential_Sources`. Or a vector like `c('red', 'blue', 'yellow')` with valid length according to your data – englealuze Dec 12 '21 at 18:36
  • Please share sample data so others can reproduce your errors. See more here [How to make a great R reproducible example?](http://stackoverflow.com/questions/5963269) – Tung Dec 13 '21 at 06:50
  • @Tung My apologies, definitely an oversight. I've tried to go back and add representative data. For some reason the tables aren't formatting cleanly after saving despite them looking fine as i edit. As such i've included a screenshot of the table information as well. – ecp.55 Dec 13 '21 at 20:27
  • @englealuze I tried both suggestions and got this the first time: "Error in as.vector(x) : object 'Relative_Contribution' not found" and this: "Error: Aesthetics must be either length 1 or the same as the data (1): y" with the vector method. – ecp.55 Dec 13 '21 at 20:52
  • The header in your data is `Contribution` not `Relative_Contribution`, that's why it was not found. Same for `Sources`. Just try something simple like `ggpie(df, Contribution, label = "Relative_Contribution", fill = Contribution)` – englealuze Dec 14 '21 at 11:07
  • @englealuze indeed that was a failure to recreate my data precisely above (newbie failure) I apologize and have updated the post again. To that end though, when I input `ggpie(df, Relative_Contribution, label = "Relative_Contribution", fill = Relative_Contribution, color = "white", size = 1.5, palette = c("#636363", "#cccccc", "#969696"))` I get: `Error in as.vector(x) : object 'Relative_Contribution' not found ` after running the for loop. – ecp.55 Dec 14 '21 at 15:35
  • see my answer and test it please. It is exactly same as your method with a small syntax fix... – englealuze Dec 14 '21 at 16:23

1 Answers1

2

This works for me

library(tibble)
library(dplyr)
library(ggpubr)

DZmix_SC1 <- tibble(
  Sample_ID = rep('SC1_18', 3), 
  Potential_Sources = c('Uintas', 'Sierra Madre', 'CMB'), 
  Relative_Contribution = c(0,22,78),
  Metric = rep('KV', 3)
)

DZmix_5_SC <- tibble(
  Sample_ID = rep('5-SC_18', 3), 
  Potential_Sources = c('Uintas', 'Sierra Madre', 'CMB'), 
  Relative_Contribution = c(0,29,71),
  Metric = rep('KV', 3)
)

DZmix_PL3 <- tibble(
  Sample_ID = rep('PL3_18', 3), 
  Potential_Sources = c('Uintas', 'Sierra Madre', 'CMB'), 
  Relative_Contribution = c(69,0,31),
  Metric = rep('KV', 3)
)

Sample_list <- c("DZmix_SC1", "DZmix_5_SC", "DZmix_PL3")

DZpie.fn <- function(df,title) {
  df <- df  %>% 
    mutate(Relative_Contribution = round(Relative_Contribution,1)) %>%
    arrange(desc(Potential_Sources))
  ggpie(df, "Relative_Contribution", label = "Relative_Contribution",
        fill = "Potential_Sources", color = "white", size = 1.5,
        palette = c("#636363", "#cccccc", "#969696"),
        lab.pos = c("in"),
        lab.font = c(0, "bold", "black")) +
  theme(legend.position = "none", 
        panel.background = element_rect(fill = "transparent"), 
        plot.background = element_rect(fill = "transparent", color = NA)) 
} 

for(i in Sample_list){
  print(DZpie.fn(get(i), i)) 
}

Your method is actually correct. You just miss placed + before lab.pos = c("in").

Then you can save images using

for (i in Sample_list){
  ggsave(DZpie.fn(get(i), i), filename=paste0("temp/",i,".png"))
}

Or equivalently but without for loop

purrr::walk(Sample_list, function(name) ggsave(DZpie.fn(get(name), name), 
                                               filename=paste0("temp/",name,".png")))
Dharman
  • 30,962
  • 25
  • 85
  • 135
englealuze
  • 1,445
  • 12
  • 19