Schleifen: Grafiken erstellen und individuell speichern

Wie rufe ich R-Funktionen auf, wie selektiere ich Daten, ich weiß nicht genau ....

Moderatoren: EDi, jogo

Antworten
Laubsauger

Schleifen: Grafiken erstellen und individuell speichern

Beitrag von Laubsauger »

Hallo,

ich habe zwei (vorerst, später werden es noch mehr) data.frames mit den geschmeidigen Namen GRCYPT_flows und ESIEIT_flows. Beide enthalten genau dieselben Variablen, nämlich report_ctry, partner_ctry, indicator, year, value.

Ich möchte nun für beide frames dieselbe Grafik erstellen und unter zwei verschiedenen Namen abspeichern. Anstatt zweimal denselben Code zu schreiben, ist es natürlich bequemer, eine Schleife zu benutzen. Hier stehe ich allerdings vor dem Problem, dass ich es nicht hinbekomme R zu sagen, dass es mir die Grafiken in zwei verschiedenen listen mit unterschiedlichen Namen abspeichert. Ich habe hier selbst schon mit der foreach-Schleife hantiert:

Code: Alles auswählen

foreach (i=c(GRCYPT_flows, ESIEIT_flows)) %do% {
  ggplot(i, aes(year, value)) + 
    geom_line(aes(colour=partner_ctry, linetype=indicator)) + facet_wrap(~report_ctry) +
    theme(axis.text.x=element_text(angle=90, vjust=0.5)) + 
    scale_x_continuous(breaks=seq(2002, 2012, 2), name="") +
    scale_y_continuous(name="Billion Euros") + 
    scale_colour_discrete(breaks=c("EA19", "ROW_NON_EA19"), labels=c("EA19", "Extra-EA19")) +
    scale_linetype_discrete(breaks=c("EA19", "ROW_NON_EA19"), labels=c("Trade", "Capital")) +
    theme(legend.title=element_blank())
}
Hier bin ich noch nichtmal so weit gekommen, etwas speichern zu können, da hier schon eine Fehlermeldung auftaucht: task 1 failed - "ggplot2 doesn't know how to deal with data of class factor".

Auf stack overflow habe ich den folgenden Lösungsent empfohlen bekommen:

Code: Alles auswählen

my_data  <- list(GRCYPT_flows, ESIEIT_flows)
my_plot <- lapply(my_data, function(i) {
ggplot(i, aes(year, value)) + 
geom_line(aes(colour=partner_ctry, linetype=indicator)) + facet_wrap(~report_ctry) +
theme(axis.text.x=element_text(angle=90, vjust=0.5)) + 
scale_x_continuous(breaks=seq(2002, 2012, 2), name="") +
scale_y_continuous(name="Billion Euros") + 
scale_colour_discrete(breaks=c("EA17", "ROW_NON_EA17"), labels=c("EA17", "Extra-EA17")) +
scale_linetype_discrete(breaks=c("EA17", "ROW_NON_EA17"), labels=c("Trade", "Capital")) +
theme(legend.title=element_blank())
})
Das funktioniert soweit erstmal, allerdings werden alle plots in my_plot gespeichert. Ich hätte das aber gerne in zwei verschiedenen Listen. Deswegen hilft mir auch der entsprechende Thread im FAQ-Bereich leider nicht weiter, denn dort geht es auch darum, die Informationen aus jeder Iteration in einer Variablen zu speichern.

Oder noch einmal anders formuliert. Ich würde gerne das folgende in einem Schleifen-Befehl zusammenfassen:

Code: Alles auswählen

plot1a <- ggplot(GRCYPT_flows,aes(year,value)) +
  geom_line(aes(colour=partner_ctry,linetype=indicator)) + facet_wrap(~report_ctry) +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) +
  scale_x_continuous(breaks=seq(2002, 2012, 2), name="") +
  scale_y_continuous(name="Billion Euros") +
  scale_colour_discrete(breaks=c("EA19","ROW_NON_EA19"), labels=c("EA19","Extra-EA19")) +
  scale_linetype_discrete(breaks=c("TRADE_IM","VALUE"), labels=c("Trade","Capital")) +
  theme(legend.title=element_blank())
  
plot1b <- ggplot(ESIEIT_flows,aes(year,value)) +
  geom_line(aes(colour=partner_ctry,linetype=indicator)) + facet_wrap(~report_ctry) +
  theme(axis.text.x=element_text(angle=90,vjust=0.5)) +
  scale_x_continuous(breaks=seq(2002,2012,2),name="") +
  scale_y_continuous(name="Billion Euros") +
  scale_colour_discrete(breaks=c("EA19","ROW_NON_EA19"), labels=c("EA19","Extra-EA19")) +
  scale_linetype_discrete(breaks=c("TRADE_IM","VALUE"), labels=c("Trade","Capital")) +
  theme(legend.title=element_blank())
Womöglich ist das Problem gar nicht so schwer zu lösen. In Stata würde das mit foreach jedenfalls ziemlich easy funktionieren. Aber R ist für Neueinsteiger wie mich leider sehr viel schwieriger zugänglich.
Zuletzt geändert von Laubsauger am Do Apr 13, 2017 9:13 am, insgesamt 3-mal geändert.
jogo
Beiträge: 2086
Registriert: Fr Okt 07, 2016 8:25 am

Re: Schleifen: Grafiken erstellen und individuell speichern

Beitrag von jogo »

Hallo Laubsauger,

willkommen im Forum!
Deine Frage auf SO war folgende?
http://stackoverflow.com/questions/4336 ... ata-frames
allerdings werden alle plots in my_plot gespeichert.
Ich sehe momentan nicht, wo my_plot auftaucht ...
Du kannst aber der bisher anonyme Funktion einen Namen geben:

Code: Alles auswählen

plotte.einen.DF <- function(i) {
    ggplot(i, aes(year, value)) + 
    geom_line(aes(colour=partner_ctry, linetype=indicator)) + facet_wrap(~report_ctry) +
    theme(axis.text.x=element_text(angle=90, vjust=0.5)) + 
    scale_x_continuous(breaks=seq(2002, 2012, 2), name="") +
    scale_y_continuous(name="Billion Euros") + 
    scale_colour_discrete(breaks=c("EA17", "ROW_NON_EA17"), labels=c("EA17", "Extra-EA17")) +
    scale_linetype_discrete(breaks=c("EA17", "ROW_NON_EA17"), labels=c("Trade", "Capital")) +
    theme(legend.title=element_blank())
}
Dann kannst Du die Aufrufe einzeln durchführen:

Code: Alles auswählen

plot1a <- plotte.einen.DF(GRCYPT_flows)
plot1b <- plotte.einen.DF(ESIEIT_flows)
Ist es das, was Du möchtest?

Gruß, Jörg
Laubsauger

Re: Schleifen: Grafiken erstellen und individuell speichern

Beitrag von Laubsauger »

Ja, das war die Frage auf SO. Die Seite ist gut, wenn man schnell erste Antworten möchte, aber wenn das nicht gleich hilft, gehen die Fragen leider schnell in der riesen Masse unter. Das my_plot ist da irgendwo beim Kopieren verloren gegangen, auf diese Variable sollte sich der lapply-Befehl beziehen. Ich hab das mal korrigiert. Ist aber egal, deine Lösung funktioniert. Herzlichen Dank. :)

€: Nein, Moment mal. Jetzt fällt mir auf: Wie sage ich der Funktion denn eigentlich, welche Werte für i eingesetzt werden? Das fehlt ja noch.

€² (09:22): Es funktioniert jetzt mit dem folgenden Code:

Code: Alles auswählen

plotdata  <- list(GRCYPT_flows, ESIEIT_flows, NLBELU_flows, DEFR_flows)
plots = lapply(plotdata, function(i) {
  ggplot(i, aes(year, value)) + 
    geom_line(aes(colour=partner_ctry, linetype=indicator)) + facet_wrap(~report_ctry) + 
    scale_x_continuous(breaks=seq(2002, 2012, 2), name="") +
    scale_y_continuous(name="Billion") + 
    scale_colour_discrete(breaks=c("EA17", "ROW_NON_EA17"), labels=c("EA17", "Extra-EA17")) +
    scale_linetype_discrete(breaks=c("EA17", "ROW_NON_EA17"), labels=c("Trade", "Capital")) +
    theme(axis.text.x=element_text(angle=90, vjust=0.5),legend.position="right")
})

plot1 <- plots[1:2]
plot2 <- plots[3:4]
Allerdings fehlt überall die Legende und ich kann nicht erkennen, warum. Gestern wurde sie noch angezeigt.
jogo
Beiträge: 2086
Registriert: Fr Okt 07, 2016 8:25 am

Re: Schleifen: Grafiken erstellen und individuell speichern

Beitrag von jogo »

Laubsauger hat geschrieben: Do Apr 13, 2017 8:41 am Ja, das war die Frage auf SO. Die Seite ist gut, wenn man schnell erste Antworten möchte, aber wenn das nicht gleich hilft, gehen die Fragen leider schnell in der riesen Masse unter.
vor allem muss man sich an die Qualitätsstandards bei den Fragen halten im Sinne von viewtopic.php?f=20&t=11
Das my_plot ist da irgendwo beim Kopieren verloren gegangen, auf diese Variable sollte sich der lapply-Befehl beziehen. Ich hab das mal korrigiert. Ist aber egal, deine Lösung funktioniert. Herzlichen Dank. :)

€: Nein, Moment mal. Jetzt fällt mir auf: Wie sage ich der Funktion denn eigentlich, welche Werte für i eingesetzt werden? Das fehlt ja noch.
Das i ist doch nur der formale Parameter in der Funktion. Wenn die Funktion aufgerufen wird, wird in i ein konkretes Objekt übergeben - in diesem Fall wird ein Dataframe erwartet. Das vorherige lapply() drumrum sorgt dafür, das aus der Liste von Dataframes ein Dataframe nach dem anderen an die Funktion übergeben wird. Die Ergebnisse (die Plots) werden wieder in einer Liste gesammelt.
€² (09:22): Es funktioniert jetzt mit dem folgenden Code:...
schön
Allerdings fehlt überall die Legende und ich kann nicht erkennen, warum. Gestern wurde sie noch angezeigt.
Die Arbeitsweise von R ist üblicherweise indifferent gegenüber dem Wochentag ;)
Es muss also an etwas anderem liegen.

Gruß, Jörg
Antworten