-2

I've tried to create a loop in order to create plots for several countries.

My dataframe: EUETS_UN

Here an excerpt of the data:

year country iso2      sector emissions
1990 Belgium   BE         ETS         0
1990 Belgium   BE       Total 120484398
1990 Belgium   BE   Regulated  78614107
1990 Belgium   BE Unregulated  41870292
1991 Belgium   BE         ETS         0
1991 Belgium   BE       Total 123544711
1991 Belgium   BE   Regulated  79811521
1991 Belgium   BE Unregulated  43733190
1992 Belgium   BE         ETS         0
1992 Belgium   BE       Total 122657813
1992 Belgium   BE   Regulated  78283962
1992 Belgium   BE Unregulated  44373851
1993 Belgium   BE         ETS         0
1993 Belgium   BE       Total 121557281
1993 Belgium   BE   Regulated  76752290
1993 Belgium   BE Unregulated  44804991
1994 Belgium   BE         ETS         0
1994 Belgium   BE       Total 124938188
1994 Belgium   BE   Regulated  80647991
1994 Belgium   BE Unregulated  44290197
1995 Belgium   BE         ETS         0
1995 Belgium   BE       Total 126082961
1995 Belgium   BE   Regulated  80518704
1995 Belgium   BE Unregulated  45564257
1996 Belgium   BE         ETS         0
1996 Belgium   BE       Total 129583625
1996 Belgium   BE   Regulated  79513349
1996 Belgium   BE Unregulated  50070276
1997 Belgium   BE         ETS         0
1997 Belgium   BE       Total 124046828
1997 Belgium   BE   Regulated  77308936
1997 Belgium   BE Unregulated  46737892
1998 Belgium   BE         ETS         0
1998 Belgium   BE       Total 130285109
1998 Belgium   BE   Regulated  82610050
1998 Belgium   BE Unregulated  47675059
1999 Belgium   BE         ETS         0
1999 Belgium   BE       Total 124745703
1999 Belgium   BE   Regulated  77595053
1999 Belgium   BE Unregulated  47150650
2000 Belgium   BE         ETS         0
2000 Belgium   BE       Total 126794789
2000 Belgium   BE   Regulated  80435088
2000 Belgium   BE Unregulated  46359701
2001 Belgium   BE         ETS         0
2001 Belgium   BE       Total 126129008
2001 Belgium   BE   Regulated  77255899
2001 Belgium   BE Unregulated  48873109
2002 Belgium   BE         ETS         0
2002 Belgium   BE       Total 126444625
2002 Belgium   BE   Regulated  77914653
2002 Belgium   BE Unregulated  48529972
2003 Belgium   BE         ETS         0
2003 Belgium   BE       Total 127953188
2003 Belgium   BE   Regulated  78464806
2003 Belgium   BE Unregulated  49488382
2004 Belgium   BE         ETS         0
2004 Belgium   BE       Total 129040883
2004 Belgium   BE   Regulated  79430967
2004 Belgium   BE Unregulated  49609916
2005 Belgium   BE         ETS  55363232
2005 Belgium   BE       Total 125638203
2005 Belgium   BE   Regulated  77343444
2005 Belgium   BE Unregulated  48294759
2006 Belgium   BE         ETS  54775328
2006 Belgium   BE       Total 124030891
2006 Belgium   BE   Regulated  75869846
2006 Belgium   BE Unregulated  48161044
2007 Belgium   BE         ETS  52795332
2007 Belgium   BE       Total 120611398
2007 Belgium   BE   Regulated  73189198
2007 Belgium   BE Unregulated  47422201
2008 Belgium   BE         ETS  55462028
2008 Belgium   BE       Total 120659008
2008 Belgium   BE   Regulated  71854823
2008 Belgium   BE Unregulated  48804185
2009 Belgium   BE         ETS  46206936
2009 Belgium   BE       Total 107642367
2009 Belgium   BE   Regulated  61048912
2009 Belgium   BE Unregulated  46593455
2010 Belgium   BE         ETS  50103980
2010 Belgium   BE       Total 113582031
2010 Belgium   BE   Regulated  66648934
2010 Belgium   BE Unregulated  46933097
2011 Belgium   BE         ETS  46203056
2011 Belgium   BE       Total 104158641
2011 Belgium   BE   Regulated  61319344
2011 Belgium   BE Unregulated  42839297
2012 Belgium   BE         ETS  43006980
2012 Belgium   BE       Total 101394977
2012 Belgium   BE   Regulated  58934979
2012 Belgium   BE Unregulated  42459997
2013 Belgium   BE         ETS  45231176
2013 Belgium   BE       Total 101970445
2013 Belgium   BE   Regulated  58383554
2013 Belgium   BE Unregulated  43586891
2014 Belgium   BE         ETS  43853144
2014 Belgium   BE       Total  96391039
2014 Belgium   BE   Regulated  56010346
2014 Belgium   BE Unregulated  40380694
2015 Belgium   BE         ETS  44713916
2015 Belgium   BE       Total 100229492
2015 Belgium   BE   Regulated  57375031
2015 Belgium   BE Unregulated  42854461
2016 Belgium   BE         ETS  43655728
2016 Belgium   BE       Total 100243711
2016 Belgium   BE   Regulated  56702848
2016 Belgium   BE Unregulated  43540863

I have only shown the whole data for one country, since every country looks the same (apart from different figures EUETS_UN$emissions)

What I want to do is (most you will see from my code below):

  • create loop, so plots will be created for all countries
  • x axis = year; y=emissions (of a country as in EUETS_UN$iso2
  • 3 groups (curves) should be from EUETS_UN$sector: Regulated, Unregulated, ETS
  • Regulated and unregulated should be between 1990:2016; ETS between 2005:2017. This years are the years with data availability

This is what I tried:

# Sets up the loop to run from i=1 through a list of countries from vector 
'iso2'
for(i in (1:length(EUETS_UN$iso2))){

# Color settings: colorblind-friendly palette
cols <- c("#999999", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", 
"#D55E00", "#CC79A7")

# Plotting code where DATA, YEAR, etc need to be handed the right vectors
p <- ggplot() +
geom_line(EUETS_UN$emissions,aes(x=year,y=emissions,group=sector),
color=cols[1]) +
labs(x="Year",y="CO2 emissions",z="",title=paste("TITLE for",iso2[i])) + 
xlim(1990,max(year.aux)) +
ylim(-50,50) +
theme(plot.margin=unit(c(.5,.5,.5,.5),"cm"))
p

# Save plot, where the file name automatically gets a country name suffix
ggsave(p,filename=paste("./FILENAME",iso2[i],".png",sep=""),width=6.5, 
height=6)
}

However, I'm getting this "Error: data must be a data frame, or other object coercible by fortify(), not an S3 object with class uneval Did you accidentally pass aes() to the data argument?"

Any idea how I could run the loop to create the plots?

Thanks in any case!

Nordsee

Nordsee
  • 81
  • 1
  • 10
  • 1
    Seems you've referenced just a column, try `...+ geom_line(EUETS_UN, aes(x=year,y=emissions,group=sector) +...`. – jay.sf Nov 10 '18 at 08:56
  • Thank you for this, but unfortunately I'm still getting the same error – Nordsee Nov 10 '18 at 09:01
  • The `color=cols[1]` should also be included into the `aes()`, And specify the `data` argument explicitly: `ggplot() + geom_line(data=EUETS_UN, aes(x=year, y=emissions, group=sector, color=cols[1]))` – jay.sf Nov 10 '18 at 09:16
  • same error, this also still includes the sector "total" – Nordsee Nov 10 '18 at 09:19
  • your code is not reproducible. You are using objects ( `iso2` and `year.aux`) which you haven't defined. Therefore downvote. Happy to remove it when you have corrected this. Would recommend to run your code in empty/fresh R sessions to check for such problems. – tjebo Nov 10 '18 at 12:03
  • @Tjebo you are right. After adding the data you can see now for another country, everything was formatted by SO to the earlier non-reproducible example. `iso2` is a column of the dataframe. I'm unclear on what year.aux is doing... – Nordsee Nov 10 '18 at 12:22
  • What do you mean you are unclear about what `year.aux` is doing? I had edited the data previously so that it is better readable. I would suggest using `dput()` . and try to avoid using so many rows, filter it down to the necessary bits to reproduce your problem. And remove the objects or define them which are causing the code to be not reproducible – tjebo Nov 10 '18 at 12:59
  • @Tjebo sorry, I can;t follow.... – Nordsee Nov 10 '18 at 13:42
  • 3
    Then have a good look at those links here: https://stackoverflow.com/help/mcve https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – tjebo Nov 10 '18 at 13:45

1 Answers1

3

Try this:

cols <- c("#999999", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", 
          "#D55E00", "#CC79A7")

iso_2s <- unique(EUETS_UN$iso2)

for(i in iso_2s) {

  # Color settings: colorblind-friendly palette
  cols <- c("#999999", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", 
            "#D55E00", "#CC79A7")

  df_to_plot <- subset(EUETS_UN, iso2 == i)
  df_to_plot <- df_to_plot[df_to_plot$sector != "Total"]
  df_to_plot$sector <- as.character(df_to_plot$sector)

  # Plotting code where DATA, YEAR, etc need to be handed the right vectors
  p <- ggplot(df_to_plot) +
    geom_line(aes(x= year,y= emissions,group = sector, color = sector)) +
    labs(x="Year",y="CO2 emissions",z="",title=paste("TITLE for",i)) + 
    xlim(1990,max(df_to_plot$year)) +
    #ylim(-50,50) +
    theme(plot.margin=unit(c(.5,.5,.5,.5),"cm")) +
    scale_color_manual(values = cols)

  print(p)

  ggsave(p,filename=paste("./FILENAME",i,".png",sep=""),width=6.5, 
         height=6)

}

This is what I get from your test example:

enter image description here

You may also want to disable scientific notation on y axis. In this case, just add + scale_y_continuous(labels = scales::comma) after the last ggplot statement, i.e. after scale_color_manual(values = cols) in this case. You'd then get:

enter image description here

I've also checked with adding artificially another country, and the loop produces 2 charts as desired.

arg0naut91
  • 14,574
  • 2
  • 17
  • 38
  • Thank you, but in your solution a wide range of rows has been removed, as not all rows contain data (data availability for Regulated & Unregulated is different than for ETS). The legend of the graph also contains a curve for "total" which was supposed to be excluded – Nordsee Nov 10 '18 at 09:11
  • "Error in paste("./FILENAME", iso2[i], ".png", sep = "") : object 'iso2' not found In addition: Warning message: Removed 94 rows containing missing values (geom_path). " – Nordsee Nov 10 '18 at 09:12
  • The solution now excludes Total as well as corrects the error in ggsave. For the removal of rows, unfortunately I cannot really know what is causing it & how it should be corrected. It would helpful if you provide a more comprehensive test data and also indicate which rows should not be removed. – arg0naut91 Nov 10 '18 at 09:23
  • Thank you, I've just ran your code. However, there are no curves on the plots and total is still included, but the loop works. Row are still removed, which may be a result due to varying data availability for the years (Regulated and unregulated 1990:2016; ETS 2005:2017). The curves should just go as the data is available (start/end). How can I provide you with more test data? – Nordsee Nov 10 '18 at 09:28
  • I've modified the code; I think total was still included because your sector variable is a factor - I've changed that to character and it should work. For the test data, I think it would be helpful if the data is more representative of what you have (more data points [years and sectors] essentially, perhaps for just 2 countries would be enough). Perhaps setting the x and y limits is the problem, or you don't have enough variability in the data, or something else. – arg0naut91 Nov 10 '18 at 09:34
  • My data preview shows now the entire data for one country. I've tried your edited solution, but it ubsets dataframe to Austria only (first in list) – Nordsee Nov 10 '18 at 11:10
  • Could that be because you have applied it to dataframe with only Austria? Could you also include few points of another country in the example? – arg0naut91 Nov 10 '18 at 11:29
  • I've added another country. I have also run the code as provided (after adjusting the dataframe references). It then automatically subset the original df `EUETS_UN`. It actually didn't do this to Austria only (I'm not clear on which basis), but the number of observations got heavily reduced – Nordsee Nov 10 '18 at 11:45
  • Unfortunately, my data example got fully screwed up when extending it. I'll reduce it to one country example – Nordsee Nov 10 '18 at 12:09
  • @Nordsee, the problem was in the `ylim(-50,50)` - I've commented it out now (you can also simply remove it) and edited the post, and it works, at least for me. – arg0naut91 Nov 10 '18 at 14:18
  • this is excellent! Thank you so much! I have it working now, but would only need the ETS line to start at the respective value and not to "jump up from zero". – Nordsee Nov 15 '18 at 19:07