z-Transformation für eine variable Anzahl von Indikatoren

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

Moderatoren: EDi, jogo

Antworten
benne
Beiträge: 10
Registriert: Mo Okt 08, 2018 1:42 pm

z-Transformation für eine variable Anzahl von Indikatoren

Beitrag von benne » Di Okt 08, 2019 3:28 pm

Hallo zusammen,

für mich geht es jetzt mit R immer weiter ans eingemachte, aber gerade stehe ich wie der Ochs vorm Berg.

Ich habe etliche Indikatoren, die ich mittels z-Transformation standardisieren und anschließend klassieren möchte.

Als Beispiel hier mal ein Auszug aus Bevölkerungsdaten nach Altersgrupen:

Code: Alles auswählen

id	ew_bst_sum	qew_bst_0bu3	qew_bst_3bu6	qew_bst_6bu10
11	4553		3.382385	2.965078	4.238963
12	2433		2.794903	3.123716	3.699137
13	2046		2.492669	2.785924	3.225806
14	2176		2.297794	3.079044	3.814338
15	7034		2.857549	2.772249	3.284049
16	8375		2.626866	2.531343	3.450746
17	7667		3.573758	3.521586	4.199817
Für einen einzelnen Indikator habe ich die folgende Routine geschrieben:

Code: Alles auswählen

# Daten einlesen
data_ind <- data.table(read.xlsx(FILE_DATA_IMP))

#1. Anzahl der Fälle
n <- nrow(data_ind)

#2. Anteilswert für die Gesamtstadt berechnen
mw <- weighted.mean(data_ind$qew_bst_0bu3,data_ind$ew_bst_sum)

#3. Standardabweichung berechnen mit mw für die Gesamtstadt
sd <- sqrt((1/(n-1)) * (sum((data_ind$qew_bst_0bu3 - mw) ^ 2)))

# 4. z-Wert bestimmen
data_ind$z_qew_bst_0bu3<-scale(data_ind$qew_bst_0bu3, center=mw, scale=sd)

# 5. Klassen zuweisen
data_ind$kls_qew_bst_0bu3 <- case_when(
  data_ind$z_qew_bst_0bu3 >= 1.5 ~ 2,
  data_ind$z_qew_bst_0bu3 >= 0.5 & data_ind$z_qew_bst_0bu3 < 1.5 ~ 1,
  data_ind$z_qew_bst_0bu3 > -0.5 & data_ind$z_qew_bst_0bu3 < 0.5 ~ 0,
  data_ind$z_qew_bst_0bu3 > -1.5 & data_ind$z_qew_bst_0bu3 <= -0.5 ~ -1,
  data_ind$z_qew_bst_0bu3 <= -1.5 ~ -2
)
Damit generiere ich zur Spalte qew_bst_0bu3 die beiden Spalten zqew_bst_0bu3 und kls_qew_bst_0bu3.
So weit, so gut!

Jetzt möchte ich das Ganze aber für alle Spalten, die mit "q" beginnen entsprechend machen.
Also zu jedem Indikator eben den z-Wert und die entsprechende Klasse in den Datensatz schreiben.

Das klingt im Grunde nach einer völlig simplen Angelegenheit.
Aber irgendwie will der Groschen bei mir nicht fallen.

Kann mir jemand auf die Sprünge helfen?
Das wäre echt super.

Vielen Dank schonmal im Voraus
Benne
Ein Freund ist jemand, der sich deinen Müll anhört, dir sagt dass es Müll ist und trotzdem weiter zuhört.
Robin Williams

jogo
Beiträge: 1478
Registriert: Fr Okt 07, 2016 8:25 am

Re: z-Transformation für eine variable Anzahl von Indikatoren

Beitrag von jogo » Do Okt 10, 2019 12:50 pm

Hallo Benne,

willkommen im Forum!
Aus welchem Paket ist die Funktion case_when() :?:
... oder hast Du Dir etwas Eigenes geschrieben?
Kennst Du die Funktion cut() :?:

Wenn man irgendeine Funktionalität öfter nutzen möchte, schreibt man eine entsprechende Funktion.
Wenn ich Dich richtig verstanden habe, möchtest Du zu verschiedenen Spalten, die alle mit q anfangen, jeweils zwei neue Spalten erzeugen, richtig?

Gruß, Jörg

bigben
Beiträge: 1061
Registriert: Mi Okt 12, 2016 9:09 am

Re: z-Transformation für eine variable Anzahl von Indikatoren

Beitrag von bigben » Do Okt 10, 2019 2:52 pm

Hallo Jörg,
jogo hat geschrieben:
Do Okt 10, 2019 12:50 pm
Kennst Du die Funktion cut() :?:
wir sind uns natürlich sofort einig, dass dieses case_when-Monster aus dplyr in dieser Form schrecklich ist. Insbesondere die Häufung von langen Variablennamen bietet Unmengen Versteckmöglichkeiten für Tippfehler. Die von Dir vorgeschlagene Funktion cut liefert einen factor zurück, was wahrscheinlich in 99% der Fälle auch am besten ist. Hier soll aber eine Zahl zurückgegeben werden. Dafür gibt es in Standard-R die Funktion findInterval.

Mein naiver Kürzungsvorschlag anstelle von case_when lautet damit

Code: Alles auswählen

beispielwerte <- c(-4.5, -4, -1.51, -1.2,-.51, 0, .49, .51, 1, 2, +Inf)
findInterval(beispielwerte, vec = c(-1.5, -.5, .5, 1.5))-2
Leider klappt das in den Grenzfällen nicht immer. So ist in der obigen case_when-Codierung dem z-Wert -0,50000 das Ergebnis -1 zuzuordnen, findIntervall macht das aber noch eine Null draus:

Code: Alles auswählen

> findInterval(-.5, vec = c(-1.5, -.5, .5, 1.5))-2
[1] 0

Was jetzt die eleganteste und übersichtlichste, damit fehlerunanfälligste Lösung ist, weiß ich noch nicht.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte

Antworten