Datencodierung ändern/anpassen

Wiederkehrende Fragen zum Forum

Moderator: EDi

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

Datencodierung ändern/anpassen

Beitrag von bigben »

Hallo Forum,

in meiner Wahrnehmung häufen sich die Fragen, wie eine kategoriale Variable in eine andere Codierung überführt werden kann.

Beispiele sind
Innerhalb einer Frage (Variable) zum Bildungshintergrund [...] möchte ich die Antworten 2-8 und 13 (ohne Studienabschluss) mit einer 0 und die Antworten 9-12 ( mit Studienabschluss) mit einer 1 kodieren.
viewtopic.php?p=10595#p10595

oder
ich habe eine Variable ("Welche der folgenden Quellen vertrauen sie am meisten wenn es um Impfinformationen geht?") mit einer Mehrfachauswahl von 1 bis 11. [...] Nun möchte ich eine neue Variable erstellen, die lediglich die Ausprägung 5,also das Internet als Infoquelle und die Ausprägung 6, online social networks, beinhaltet.
viewtopic.php?f=22&t=2131

oder
Ich würde gerne einen t-test durchführen um zu schauen, ob Frauen ein höheres Stresserleben aufweisen aus Männer. Nun habe ich aber im Geschlecht auch divers. Ich würde diese nun gerne mit NA ersetzen.
viewtopic.php?f=11&t=2077

oder
wie recodiere ich eine fünfstufige Variable in eine dichotome?
viewtopic.php?f=11&t=1931

oder
"5" soll zur neuen "1" werden
"1" und "2" sollen zur neuen "2" werden
und "3" und "4" sollen zur neuen "3" werden.
viewtopic.php?f=7&t=1776

und es gibt viele weitere Beispiele, aber Ihr glaubt mir bestimmt, dass es eine FAQ ist. Ganz offensichtlich ist das eine grundlegende Funktion für jedes Statistikprogramm und in einem so alten und offenen System wie R gibt es dafür natürlich nicht nur eine Antwort, sondern im Laufe der Zeit sind viele Antworten gefunden worden.

Ich würde in diesem Thread gerne Posts von erfahrenen R'lern sehen, die in je einem Beitrag je eine Herangehensweise darstellen. Gerne können die Vor- und Nachteile der Methoden diskutiert werden, aber alles was nicht streng der Methodendarstellung dient, bitte ich aus diesem Thread herauszuhalten. Jeder, der sein je eigenes Problem besprechen möchte, darf das in seinem je eigenen Thread tun, aber nicht hier. Bei Zuwiderhandlung ist großzügiges Beiträgelöschen zum Wohle der später kommenden hiermit angesagt!

GLG,
Bernhard

-------------------------------------------------------------------------------------------------------------


Beispielproblem 1:

Code: Alles auswählen

bsp1 <- c(-21.91, 7.31, 49.17, 5.0, 17.29, 10.22, -20.03, 25.06, 9.82, 
7.26, -32.53, 17.83, 23.65, -12.9, 13.85, -2.33, 19.19, 25.43, 
34.71, -13.23, 36.13, -5.49, 25.78, 21.36, 2.95, 0.18, -15.61, 
33.37, -13.47, -13.27, -14.64, 4.32, 12.68, 18.26, 7.8, -4.7, 
1.96, -30.54, 6.47, -1.67, 28.63, 43.49, 18.79, 26.98, -7.52, 
-2.9, -15.79, -16.06, 5.11, -24.25, -4.92, -50.87, 1.19, 4.27, 
32.86, 12.74, -17.83, 9.43, -18.69, 9.32, -14.19, 5.14, -26.34, 
-0.96, 36.66, 17.77, 24.13, 25.7, -12.36, 19.86, 1.01, -25.23, 
-32.06, 23.12, -11.02, -38.24, 9.69, 8.44, 8.91, -12.89, 31.54, 
1.27, -1.18, 31.72, -12.31, 22.48, 11.97, -4.26, 13.52, 3.81, 
22.61, 17.75, 11.97, -6.43, -8.67, -30.82, 5.31, 32.27, 15.49, 
-19.52)
Bilde daraus 3 Gruppen, eine für Werte unter -5, eine für Werte über 5 und eine für dazwischen.

Beispielproblem 2:

Code: Alles auswählen

bsp2 <- c("Diverse(r)", "Diverse(r)", "Diverse(r)", "unbekannt", "Mann", 
"Frau", "Diverse(r)", "Mann", "Frau", "Frau", "unbekannt", "Mann", 
"Mann", "unbekannt", "unbekannt", "Mann", "unbekannt", "Mann", 
"Diverse(r)", "Frau", "unbekannt", "unbekannt", "unbekannt", 
"Diverse(r)", "unbekannt", "unbekannt", "unbekannt", "Frau", 
"Frau", "Mann")
Mache daraus etwas t-test-taugliches für den Mann/Frau-Vergleich


Beispielproblem 3:

Code: Alles auswählen

bsp3 <- c(0L, 1L, 7L, 8L, 1L, 2L, 4L, 9L, 1L, 8L, 9L, 3L, 7L, 5L, 4L, 
8L, 9L, 3L, 5L, 9L, 8L, 7L, 4L, 5L, 4L, 2L, 4L, 8L, 7L, 8L, 1L, 
9L, 0L, 5L, 7L, 0L, 1L, 3L, 3L, 6L, 8L, 3L, 0L, 4L, 4L, 0L, 8L, 
9L, 8L, 0L)
Mache alle Werte 0 zu NA, vom Rest mache eine Gruppe für gerade und eine für ungerade Werte.
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte

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

Re: Datencodierung ändern/anpassen

Beitrag von bigben »

Hallo!

Und da bin ich gleich wieder mit meiner Lieblingslösung, aber YMMV. Da ich sowas nur gelegentlich recodiere habe ich keine Lust, mir die Syntax von Spezialfunktionen wie car::recode zu merken. Dafür schreibe ich dann lieber ein wenig extra Code. Das ist nicht die kürzeste Variante, aber sie ist sehr vielseitig anpassbar. Im Wesentlichen braucht man dafür eine Funktion, die mit if's jeden Einzelfall abdeckt:

Code: Alles auswählen

unterteile_bsp_1 <- function(x){
    if(x < -5.0) return("negativ")
    if(x > -5 & x < 5) return("ungefähr Null")
    if(x > 5) return("positiv")
    stop("Fallunterscheidung nicht gelungen!")
}
Auf zwei Dinge möchte ich hinweisen: im zweiten if findet ihr das Zeichen & als logisches 'UND'. Das logische 'ODER' wäre |:

Code: Alles auswählen

> TRUE & FALSE
[1] FALSE
> TRUE & TRUE
[1] TRUE
> TRUE | FALSE
[1] TRUE
> FALSE | FALSE
[1] FALSE
Außerdem einen Hinweis wert: Ich habe in meiner Funktion einen Fehler: Sie kann den Fall x == -5 und den Fall x == 5 nicht abdecken. Solche Fehler können vorkommen, dafür habe ich die stop-Funktion am Ende, die mich ggf. auf den Fehler hinweist. In vielen Fällen kann man dieses stop einfach durch ein return(standardwert) ersetzen.

So eine kleine Funktion ist auch mit Anfängerkenntnissen meist schnell geschrieben. Besonders leicht auf ganze Spalten anzuwenden wird sie mithilfe der Funktion "Vectorize". Man achte auf die Großschreibung:

Code: Alles auswählen

bsp <- data.frame(alt = bsp1)

unterteile <- Vectorize(function(x){
    if(x < -5.0) return("negativ")
    if(x >= -5 & x <= 5) return("ungefähr Null")
    if(x > 5) return("positiv")
    stop("Fallunterscheidung nicht gelungen!")
})

bsp$neu <- unterteile(bsp$alt)
head(bsp)
Natürlich muss man so eine Funktion nicht per Vectorize anwenden, man könnte auch Map oder sapply oder eine for-Schleife verwenden.
Nehmen wir für Beispiel 2 an, dass Diverse dem Zufall folgend für den t-Test teils als Mann und Teils als Frau codiert werden sollten.

Code: Alles auswählen

genderdf <- data.frame(gender = bsp2, value =  runif(30,0,10))

codiere <- function(gender){
    if(gender == "Mann") return("m")
    if(gender == "Frau") return("f")
    if(gender == "Diverse(r)") return(sample(c("m", "f"),1))
    if(gender == "unbekannt") return(NA)
    stop("Fallunterscheidung nicht gelungen!")
}

genderdf$gender.dicho <- sapply(genderdf$gender, codiere)

t.test(value ~ gender.dicho, data = genderdf)

Nachteile dieses Lösungsansatzes: Es entsteht viel Code und damit viele Gelegenheiten, kleine Fehler einzubauen.

Vorteile dieses Lösungsansatzes: Man muss keine packages einbinden und keine Spezialsyntax lernen. Man braucht das, was man ohnehin im Umgang mit R lernen sollte. Außerdem ist die Lösung sehr flexibel: Ob nun eine, zwei oder drei Spalten ausgewerten werden müssen ist kein Problem und auch der Zufallsrückgabewert oben war leicht umzusetzen.

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

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

Re: Datencodierung ändern/anpassen

Beitrag von bigben »

Natürlich geht das knapper und eleganter. Gern genommen ist die Funktion recode, deren Syntax so schwierig dann auch nicht ist und die sehr vielseitig ist. Dafür müsst Ihr aber zunächst das Paket "car" installieren. Einfach mit

Code: Alles auswählen

install.packages("car")
library(car)
Hier gibt es ein Beispiel auf den Seiten des Forenbetreibers: https://www.r-statistik.de/R_erweitern/ ... tml#recode

Hier ein Beispiel in diesem Thread:

Code: Alles auswählen

genderdf <- data.frame(gender = bsp2)

genderdf$gender.dicho <- car::recode(bsp2,  "'Mann'='m'; 'Frau'='f'; 
            'Diverse(r)'=NA; 'unbekannt'=NA", as.factor=FALSE)

head(genderdf)
Die Bedienungsanleitung ist hier: https://www.rdocumentation.org/packages ... ics/recode

Vorsicht, denn der Name recode ist zu verlockend. Auch das Package dplyr hat eine gleichnamige Funktion die ähnliches leistet aber eine etwas andere Syntax hat und bestimmt gibt es da draußen noch mehr Code, der eine Funktion diesen Namens hat. Deshalb schlage ich die kaum längere aber eindeutige Schreibweise car::recode vor.
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte

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

Re: Datencodierung ändern/anpassen

Beitrag von jogo »

Meine wichtigsten Werkzeuge beim umkodieren:
cut(), ifelse(), recode(), merge(),
... manchmal auch %in% oder indizieren mit einem logischen Vektor.

Gruß, Jörg

Antworten