Condition abhängige Summation

Allgemeine Statistik mit R, die Test-Methode ist noch nicht bekannt, ich habe noch keinen Plan!

Moderatoren: EDi, jogo

flowe
Beiträge: 6
Registriert: Di Mai 14, 2019 12:57 pm

Condition abhängige Summation

Beitrag von flowe »

Hallo,
dies ist mein erster Beitrag in dem Form deshalb erstmal Hallo :)

Ich helfe einer Bekannten bei einer Bachelor-Arbeit, da sie nicht so fit in Sachen programmieren ist. Ich selbst bin Softwareentwickler aber mit R kenne ich mich nicht aus. Habe erst begonnen.

Nun zu meinem Problem:
Ich habe aus der WHO-Datenbank Daten zur Sterberate von Menschen aus Süd-Afrika exportiert. Diese Daten möchte ich nun analysieren.
Ich habe festgestellt, dass in der Altersgruppe um 30 in einigen Jahren viele Menschen starben. Das möchte ich nun näher untersuchen.
Dabei bin ich auch schon recht weit gekommen, aber ich komme jetzt einfach nicht mehr weiter. Ich habe folgende Struktur der Daten (Auszug)
Bild
ich möchte jetzt alle Altersgruppen ausummieren also 0, 1, 2, 3 aber nicht komplett sondern sortiert nach Cause. Im Ergebniss soll die Spalte Sex verschwinden, da ich nicht nach Geschlecht trennen möchte sondern alle Personen mich interessieren.
Man könnte das mit Schleifen etc. machen, aber so wie ich R bisher kennengelernt habe gibt es da bistimmt ne elegante Lösung.

Danke

Grüße Florian

PS: Das ist mein bisheriger Code

Code: Alles auswählen

#Lade CSV Daten der WHO
data = read.csv2("Mortality_2015_1999_Germany_SouthAfrica.csv", header = TRUE, sep = ",", check.names = FALSE)

# Hole Daten f?r ein Land
data_country = subset(data, Country == country_val)

data_countryYear = subset(data_country, Cause != "TOT")

# Take Data for one year
# data_countryYear = subset(data_countryYear, Year %in% c(2004, 2005, 2006))

# Get data where many peaple died at group 30                          
data_manyDeaths = subset(data_countryYear, `30` > 2000)

data_manyDeaths[is.na(data_manyDeaths)] = 0

data_manyDeaths = data_manyDeaths[order(data_manyDeaths$`30`), ]

# extract causes for death
data_manyDeathsCause = data_manyDeaths$Cause

# remove duplicated causes
data_manyDeathsCause = data_manyDeathsCause[!duplicated(data_manyDeathsCause)]

# drop levels which are 0
data_manyDeathsCause = droplevels(data_manyDeathsCause)

# get data with vector of causes (many deaths) from all years
data_cause = data_country[data_country$Cause %in% data_manyDeathsCause, ]
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Condition abhängige Summation

Beitrag von jogo »

Hallo Florian,

willkommen im Forum!
Kannst Du bitte mal den Output von

Code: Alles auswählen

str(data)
in Deine nächste Nachricht kopieren?

Ich kann mir vorstellen, dass man es mit einem geschickten Einsatz von aggregate() erledigen kann.
Etwa so:

Code: Alles auswählen

aggregate(. ~ Species, data=iris, FUN=sum)
Gruß, Jörg
flowe
Beiträge: 6
Registriert: Di Mai 14, 2019 12:57 pm

Re: Condition abhängige Summation

Beitrag von flowe »

Hallo Jörg,
wow das ging ja schnell. Vielen Dank schon mal. Dann wäre ich ja gar nicht so weit weg mein Versuch schaut so aus

Code: Alles auswählen

aggregate(data_cause, by = list(data_cause$Cause), FUN = sum)
klappt leider nicht :?

Hier das Ergebnis:

Code: Alles auswählen

str(data)
'data.frame':	139605 obs. of  33 variables:
 $ Code    : int  4085 4085 4085 4085 4085 4085 4085 4085 4085 4085 ...
 $ Country : Factor w/ 2 levels "Germany","South Africa": 1 1 1 1 1 1 1 1 1 1 ...
 $ Year    : int  2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 ...
 $ List    : int  104 104 104 104 104 104 104 104 104 104 ...
 $ Cause   : Factor w/ 8160 levels "A00","A009","A01",..: 7 7 8 8 9 11 11 17 18 19 ...
 $ Sex     : int  1 2 1 2 1 1 2 2 2 1 ...
 $ Format  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ All ages: int  9 4 6 3 2 2 2 1 2 1 ...
 $ 0       : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 1       : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 2       : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 3       : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 4       : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 5       : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 10      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 15      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 20      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 25      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 30      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 35      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 40      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 45      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 50      : int  0 0 0 2 1 0 0 0 1 0 ...
 $ 55      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 60      : int  1 0 1 0 1 1 0 1 0 0 ...
 $ 65      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ 70      : int  2 0 4 0 0 0 0 0 0 0 ...
 $ 75      : int  1 1 1 1 0 0 0 0 0 1 ...
 $ 80      : int  3 1 0 0 0 0 0 0 0 0 ...
 $ 85      : int  2 1 0 0 0 0 2 0 1 0 ...
 $ 90      : int  0 0 0 0 0 1 0 0 0 0 ...
 $ 95      : int  0 1 0 0 0 0 0 0 0 0 ...
 $ Unknown : int  0 0 0 0 0 0 0 0 0 0 ...
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Condition abhängige Summation

Beitrag von jogo »

Hallo Florian,

wie wäre es mit:

Code: Alles auswählen

aggregate(. ~ Cause, data=data[c(5, 9:32)], FUN = sum)
:?:

Was meinst Du mit
klappt leider nicht ! :? 
??
irgendetwas wie in

Code: Alles auswählen

library("fortunes")
fortune(324)
Und dann noch eine kleine Anmerkung zu der Benennung von Objekten. Ich würde meinen Dataframe weder dataframe noch data nennen. Aber glücklicherweise bekommt R nur in wenigen Fällen das Objekt in den falschen Rachen. Vergleiche

Code: Alles auswählen

fortune(77)
Gruß, Jörg
flowe
Beiträge: 6
Registriert: Di Mai 14, 2019 12:57 pm

Re: Condition abhängige Summation

Beitrag von flowe »

Hallo Jörg,
paam. Das hat funktioniert.
Wie sähe eine Modifikation aus wenn die Summe auch pro Jahr wäre?

Ich würde aber auch gerne verstehen warum?

Code: Alles auswählen

data=data_cause[c(5, 9:32)]
Der Teil ist plausibel. Erste Spalte nach was summiert wird und zweite über welche Spalten

Aber was bedeutet das Das ist nicht ganz trivial?

Zu deiner Frage was bei meinerm Versuch passiert:

Code: Alles auswählen

> aggregate(data_cause, by = list(data_cause$Cause), FUN = sum)
Error in Summary.factor(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,  : 
  ‘sum’ not meaningful for factors
wobei mir klar war das der Ausdruck noch nicht wirklich stimmen kann aber das war der letzt Versuch als ich euer Forum bemüht habe...

Danke

PS: Und danke für den Tip. Es ist in jeder Programmiersprache eine schlechte Idee Variablen nach Schlüsselwörtern zu bennen. Wie gesagt bin Anfänger ;)
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Condition abhängige Summation

Beitrag von jogo »

Hallo Florian,
flowe hat geschrieben: Di Mai 14, 2019 3:09 pm paam. Das hat funktioniert.
prima
Wie sähe eine Modifikation aus wenn die Summe auch pro Jahr wäre?

Code: Alles auswählen

aggregate(. ~ Year, data=data[c(3, 9:32)], FUN = sum)
Ich würde aber auch gerne verstehen warum?

Code: Alles auswählen

data=data_cause[c(5, 9:32)]
Der Teil ist plausibel. Erste Spalte nach was summiert wird und zweite über welche Spalten
:o Das ist schön. Dieser Teil ist nämlich sehr trickreich und ernöglicht erst den Einsatz des Punktes in der Formel für die Aggregation.
(es geht um die Auswahl der Spalten, ein Dataframe ist eine spezielle Liste. Hier wird mit einem Index für die Liste gearbeitet.)
Aber was bedeutet das Das ist nicht ganz trivial?
eigentlich schon:
Der Punkt steht für alle Spalten, die nicht explizit in der Formel genannt sind. Also bei:

Code: Alles auswählen

aggregate(. ~ Cause, data=data[c(5, 9:32)], FUN = sum)
ist $Cause die fünfte Spalte im Dataframe data, die 9. bis 24. Spalte sollen aggregiert werden. data[c(5, 9:32)] packt diese interessanten Spalten in einen Dataframe - dieser wird der Wert für den Parameter data=. Nachdem mit "~ Cause" die Spalte Cause für die Gruppierung verwendet wird, bleiben die anderen Spalten für den Punkt auf der linken Seite der Formel. :idea:
Zu deiner Frage was bei meinem Versuch passiert:

Code: Alles auswählen

> aggregate(data_cause, by = list(data_cause$Cause), FUN = sum)
Error in Summary.factor(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,  : 
  ‘sum’ not meaningful for factors
wobei mir klar war, dass der Ausdruck noch nicht wirklich stimmen kann aber das war der letzt Versuch als ich euer Forum bemüht habe...
o.k., mit Faktoren kann man nicht rechnen.
PS: Und danke für den Tip. Es ist in jeder Programmiersprache eine schlechte Idee Variablen nach Schlüsselwörtern zu bennen. Wie gesagt bin Anfänger ;)
Aber Du bist Softwareentwickler. Mit reservierten Wörtern ist es noch etwas heftiger:

Code: Alles auswählen

fortune(18)
Gruß, Jörg
flowe
Beiträge: 6
Registriert: Di Mai 14, 2019 12:57 pm

Re: Condition abhängige Summation

Beitrag von flowe »

Hallo Jörg,
vielen vieeeelen Dank schon mal für die Mühe. Ich werde mich später (habe jetzt dann noch einen Termin) mit deinen Erklärungen genauer beschäftigen (Habe es nicht sofort verstanden). Komme aus der Mikrocontroller mit Assembler C/C++ Ecke und da funzt das alles bischen anders ;) .

Aber ich muss sagen, dass R echt eine supercoole und mächtige Sprache ist, aber am Anfang ganz schön umfangreich was das Vokabular angeht. In C hat man if then else for... und noch ein paar. Das wars :) .

Aber mein Interesse ist geweckt auch über die Hilfe für meine Bekannte mich damit weiter zu beschäftigen...

also nochmal Daaanke... :P :)

Edit:
aggregate(. ~ Year, data=data[c(3, 9:32)], FUN = sum)
Das trifft es leider nicht ganz weil ich nach Jahr und Cause noch bräuchte... Aber wie gesagt habe es noch nicht verstanden
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Condition abhängige Summation

Beitrag von jogo »

Hallo Florian,
flowe hat geschrieben: Di Mai 14, 2019 3:40 pm Edit:
aggregate(. ~ Year, data=data[c(3, 9:32)], FUN = sum)
Das trifft es leider nicht ganz weil ich nach Jahr und Cause noch bräuchte... Aber wie gesagt habe es noch nicht verstanden
dann bitte:

Code: Alles auswählen

aggregate(. ~ Year + Cause, data=data[c(3, 5, 9:32)], FUN = sum)
Hier geht es zu den Hilfetexten:

Code: Alles auswählen

?aggregate
?formula
... oder in RStudio: das Fenster rechts unten, Tab "Help" das Suchfeld rechts oben verwenden.

Gruß, Jörg
flowe
Beiträge: 6
Registriert: Di Mai 14, 2019 12:57 pm

Re: Condition abhängige Summation

Beitrag von flowe »

Hallo Jörg,
es ist bei mir leider später als gedacht geworden. Habe deine Lösung jetzt mal eingebaut und es läuft. Aber ich muss mir das echt noch mal genau anschauen verstehe die Hintergründe noch zu wenig. Ich habe auch mal meinen gesamten Code drangehängt. CSV-Datei ist leider zu groß. Falls jemand daran interesse hätte dann kann ich die auch gerne verkürzen oder auf meinen Webspace zum download zur Verfügung stellen. Vielleicht kann ja jemand davon provitieren.

Ich bin natürlich auch offen für Kritik und Verbesserungen. Vielleicht kann man z.B. die Schleife einfach in einer Zeile hinschreiben :P (glaub ich aber nicht)

Auf jeden Fall vielen Dank nochmal an dich Jörg...

Code: Alles auswählen

#Lade CSV Daten der WHO
data = read.csv2("Mortality_2015_1999_Germany_SouthAfrica.csv", header = TRUE, sep = ",", check.names = FALSE)

# Hole Daten f?r ein Land
data_country = subset(data, Country == "South Africa")

# remove the total deaths
data_countryYear = subset(data_country, Cause != "TOT")

# Get data where many peaple died at group 30                          
data_manyDeaths = subset(data_countryYear, `30` > 2000)

# Set all data are not available to 0
data_manyDeaths[is.na(data_manyDeaths)] = 0

# Get Data for age 30
data_manyDeaths = data_manyDeaths[order(data_manyDeaths$`30`), ]

# extract causes for death
data_manyDeathsCause = data_manyDeaths$Cause

# remove duplicated causes
data_manyDeathsCause = data_manyDeathsCause[!duplicated(data_manyDeathsCause)]

# drop levels which are 0
data_manyDeathsCause = droplevels(data_manyDeathsCause)

# get data with vector of causes (many deaths) from all years
data_cause = data_country[data_country$Cause %in% data_manyDeathsCause, ]

# build sum of died people (independet of sex) per cause
result = aggregate(. ~ Year + Cause, data=data_cause[c(3, 5, 9:32)], FUN = sum)

# load library for the graph generation
library(plot3D)

# get single cause from the causes where the most people died
for (cause_val in data_manyDeathsCause)
{
  # get data by cause
  res_tmp = subset(result, result$Cause == cause_val)
  
  # extract columns with data by age
  res_plot = res_tmp[3:ncol(res_tmp)]
  
  # set filename for the picture export of the graph
  png(filename=paste(cause_val, ".png"), width = 800, height = 400)
  
  # generate graph
  image2D(x = res_tmp$Year, y = strtoi(colnames(res_plot)), z = as.matrix(res_plot), xlab="", ylab="")
  
  # set title of the graph
  title(main = paste("Cause", cause_val))
  
  # close the export device
  dev.off()
}
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Condition abhängige Summation

Beitrag von jogo »

Hallo Florian,
flowe hat geschrieben: Mi Mai 15, 2019 11:06 am Ich habe auch mal meinen gesamten Code drangehängt. CSV-Datei ist leider zu groß. Falls jemand daran interesse hätte dann kann ich die auch gerne verkürzen oder auf meinen Webspace zum download zur Verfügung stellen. Vielleicht kann ja jemand davon provitieren.

Ich bin natürlich auch offen für Kritik und Verbesserungen. Vielleicht kann man z.B. die Schleife einfach in einer Zeile hinschreiben :P (glaub ich aber nicht)
wenn Du einen Link zu der Datei mit den Daten liefern könntest, wäre es toll.
Das wäre für mich nochmal eine Motivation, meinen Code noch etwas sicherer zu gestalten.

Deinen Code werde ich mir auch noch anschauen und kommentieren.

Gruß, Jörg
Antworten