ggplot2: Fehler bei geom_text, woran liegts?

Wie erstelle ich Grafiken, was ist zu beachten?

Moderatoren: EDi, jogo

Antworten
Vermina_H

ggplot2: Fehler bei geom_text, woran liegts?

Beitrag von Vermina_H »

Hallo Leute,

Für ein Forstwirtschaftsprojekt will ich ein Balkendiagramm erstellen, dass mir den prozentualen Anteil eines Waldtypes an der Gesamtfläche eines Waldes anzeigt.

Mein Datensatz besteht aus 1241 obervations mit für diese Frage zwei relevanten Variablen:

area_ha: Fläche in Hektar eines Untersuchungsplots, im "num" Format.
MiWaReVe: 20 Klassen von Waldtypen, abgekürzt mit Nummerncodes, im "factor" Format.

Hier mal ein Minimaldatensatz von mir, als Beispiel:

Code: Alles auswählen

structure(list(Id = c(0L, 2L, 3L, 4L, 5L, 17L), MiWaReVe = structure(c(7L, 
7L, 14L, 17L, 17L, 17L), .Label = c("", "0", "1.1.", "2.1.", 
"2.2.1.", "2.2.2.", "2.3.1.", "2.3.2.", "3.1.1.", "3.1.2.", "3.2.1.", 
"3.2.2.", "3.2.3.", "4.1.", "4.2.", "5.1.", "5.2.", "6.", "7.", 
"8."), class = "factor"), area_ha = c(8.08759, 8.76723, 5.5033, 
1.22659, 4.31278, 8.23421), Owner = structure(c(2L, 2L, 2L, 2L, 
2L, 2L), .Label = c("Bundesforsten", "Kommunalwald", "Privatwald", 
"Staatswald"), class = "factor"), hint_cl = structure(c(3L, 3L, 
3L, 4L, 4L, 4L), .Label = c("A", "B", "C", "D", "E", "X"), class = "factor"), 
    area_in_per = c(0.216871128099877, 0.23509587657276, 0.147572624140449, 
    0.032891375182969, 0.115648476721321, 0.220802786950289)), .Names = c("Id", 
"MiWaReVe", "area_ha", "Owner", "hint_cl", "area_in_per"), row.names = c(NA, 
6L), class = "data.frame")
Wie gesagt, will ich nun mir mit Hilfe von ggplot2 die prozentuale Fläche jedes Waldtyps (MiWaReVe) anzeigen lassen. Dazu habe ich folgenden Code geschrieben:


Code: Alles auswählen

library("ggplot2")
library("scales")


MiWaRe=read.table(file="2017_11_MiWaRe.csv", sep=";",dec="," , header=T)

str(MiWaRe)

# total area AOI
area_total=sum(MiWaRe$area_ha)


# area of each plot in % in a new column
MiWaRe=cbind(MiWaRe, "area_in_per"=MiWaRe$area_ha/area_total*100)
MiWaRe
sum(MiWaRe$`area_in_per`) # check


ggplot(data=MiWaRe, aes(x = factor(MiWaReVe), y=((area_in_per)/sum(area_in_per))))  +            
geom_bar(stat="identity")  +           
scale_y_continuous(labels = percent)
Mit diesem Code bekomme ich eine Basisversion, von dem Barplot, den ich will.




Gerne würde ich noch mir die Prozentwerte über den Balken anzeigen lassen, und hier beginnen die Probleme. Ich habe das seit Tagen mit unterschiedlichen Abänderungen des folgenden Codes versucht:


Code: Alles auswählen

  ggplot(data=MiWaRe, aes(x = factor(MiWaReVe), y=((area_in_per)/sum(area_in_per))))  +            
  geom_bar(stat="identity")  +           
  scale_y_continuous(labels = percent)+
  geom_text(aes(label = scales::percent((area_in_per)/sum(area_in_per)), y= ..prop.. ), stat= "count", vjust = 25)
Aber das Programm fügt leider nur einen Wert in die Grafik ein (den Typ, der nur einmal in den ganzen Originaldaten auftaucht) und gibt mir folgende Warnmeldung: "Warning message:
Removed 19 rows containing missing values (geom_text)." (siehe auch Grafik 1)

Ich habe mich natürlich kundig gemacht über die Warnung, aber ich bin nicht wirklich weitergekommen und glaube kaum, dass das Problem am zu geringen Displayplatz liegt (habe auch mehrmals versucht den Anzeigebereich zu erweitern). Ich natürlich den Code auch versucht zu verändern, um das Problem zu umgehen, zumindest nach bestem Wissen und Gewissen, Beispielsweise damit:


Code: Alles auswählen

 ggplot(data=MiWaRe, aes(x = factor(MiWaReVe), y=((area_in_per)/sum(area_in_per))))  +            
                                    geom_bar(stat="identity")  +           
                                    scale_y_continuous(labels = percent)+
                                    geom_text(aes( label = scales::percent(..prop..),
                                                   y= ..prop.. ), stat= "count", vjust = -1)

Aber dabei entsteht nur das, was Grafik 2 anzeigt.


Naja, wie ihr wohl gemerkt habt, bin ich noch relativ neu in R (fuchse mich da erst seit zwei Wochen rein), aber ich würde mich über Hilfe dennoch sehr freuen. Ich hoffe dazu ist mein Post auch verständlich genug geschrieben, wenn noch etwas gebraucht wird, liefere ich es sehr gerne nach!

Liebe Grüße
Dateianhänge
Grafik 2.png
Grafik 2.png (8.71 KiB) 1287 mal betrachtet
Grafik 1.png
Grafik 1.png (8.74 KiB) 1287 mal betrachtet
Benutzeravatar
student
Beiträge: 674
Registriert: Fr Okt 07, 2016 9:52 am

Re: ggplot2: Fehler bei geom_text, woran liegts?

Beitrag von student »

Hallo Vermina,

einen schnellen Hinweis, da ich mich nicht durch Deinen R-Code gearbeitet habe: Du erhältst folgende Warnmeldung: "Warning message:
Removed 19 rows containing missing values (geom_text)" und die Betonung liegt auf "missing values" (NA's) was nichts anderes bedeutet, dass Werte fehlen. Du brauchst also eine Strategie zum Umgang mit fehlenden Beobachtungen! Du solltest Prüfen, ob deswegen die Grafik nicht wie gewünscht aussieht...
Viele Grüße,
Student
-----------------------------------------------------------------------------------------------------------------------
faes.de, Datenanalyse mit R & das Ad-Oculos-Projekt
Das Ad-Oculos-Projekt auf YouTube

Habe Mut, dich deines eigenen Verstandes zu bedienen! (Kant)
Vermina_H

Re: ggplot2: Fehler bei geom_text, woran liegts?

Beitrag von Vermina_H »

Hi Student,

vielen lieben Dank für deine Hilfe.
Ich habe jetzt versucht mit

Code: Alles auswählen

na.exclude(Daten)
eventuelle NA's auszuschließen. Ändert aber weder was an meinen gesamtobservierten Variablen, noch an der Fehlermeldung. Auch mit

Code: Alles auswählen

Daten[is.na(Daten$MiWaReVe),"MiWaReVe"] <- 1
habe ich es (natürlich angepasst an die Felder meines Datensatzes) probiert, ohne Ergebnis.



Da selbst mit meinem Beispieldatensatz aus dem ersten Post, der nur aus sechs Tabellenzeilen besteht und garantiert keine NA's enthält, die selbe Fehlermeldung bekomme, und ich auch bereits andere Diagramme mit meinem Gesamtdatensatz ohne Fehlermeldung erstellt habe, vermute ich, dass mein Problem eher in der Syntax oder an den von mir verwendeten Funktionen liegen muss...

Mal sehen, ich gebe noch nicht auf :)
Curnen
Beiträge: 27
Registriert: Fr Nov 18, 2016 3:45 pm

Re: ggplot2: Fehler bei geom_text, woran liegts?

Beitrag von Curnen »

Also ich bin generell ein Fan davon, alle benötigten Werte zuerst zu berechnen und dann "nur" zu plotten. Hilft dir denn das hier weiter?

Code: Alles auswählen

MiWaRe <- structure(list(MiWaReVe = structure(c(7L, 7L, 14L, 17L, 17L, 
                                      17L), .Label = c("", "0", "1.1.", "2.1.", "2.2.1.", "2.2.2.", 
                                                       "2.3.1.", "2.3.2.", "3.1.1.", "3.1.2.", "3.2.1.", "3.2.2.", "3.2.3.", 
                                                       "4.1.", "4.2.", "5.1.", "5.2.", "6.", "7.", "8."), class = "factor"), 
               area_ha = c(8.08759, 8.76723, 5.5033, 1.22659, 4.31278, 8.23421
               )), .Names = c("MiWaReVe", "area_ha"), class = "data.frame", row.names = c(NA, 
                                                                                          6L))


library("plyr")

# sum the total area
MiWaRe <- ddply(MiWaRe, .(MiWaReVe),summarise, area_ha_sum=(sum(area_ha)))
# calculate percentages
MiWaRe[,"percent"] = round(MiWaRe[,"area_ha_sum"]/sum(MiWaRe[,"area_ha_sum"]) * 100,2)

# calculate the positions of labels within the barchart (should be in the middle of the respective bar)

# for absolute positions
MiWaRe <- ddply(MiWaRe, .(MiWaReVe), transform, pos_abs = (cumsum(area_ha_sum) - 0.5 * area_ha_sum))
# for relative positions
MiWaRe <- ddply(MiWaRe, .(MiWaReVe), transform, pos_rel = (cumsum(percent) - 0.5 * percent))

# add a label column containing the percentages
MiWaRe[,"label"] <- paste0(sprintf("%.0f",round(MiWaRe[,"percent"],1) ), "%")
# optional: remove labels for very small sizes
plotdata[plotdata[,"percent"] < 5,"label"] <- NA


# absolute values:
library("ggplot2")

ggplot(MiWaRe, aes(x = MiWaReVe, y = area_ha_sum, fill = MiWaReVe)) + geom_bar(stat = "identity", width = .7) +  geom_text(aes(y = pos_abs, label = label))

# percent values:

ggplot(MiWaRe, aes(x = MiWaReVe, y = percent, fill = MiWaReVe)) + geom_bar(stat = "identity", width = .7) +  geom_text(aes(y = pos_rel, label = label))

Wenn du die Prozentzahlen nicht auf den Balken haben möchtest, sondern darüber kannst du einfach die Werte in pos_rel bzw. pos_abs auf einen einheitlichen geeigneten Wert ändern.

Viele Grüße
Matthias
Antworten