Neue Spalte mit Daten aus anderen Spalten unter Grouping Bedingungen auffüllen

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

Moderatoren: EDi, jogo

Antworten
kosa
Beiträge: 27
Registriert: Mo Sep 02, 2019 6:47 pm

Neue Spalte mit Daten aus anderen Spalten unter Grouping Bedingungen auffüllen

Beitrag von kosa »

Liebe Alle,

Ich habe einen Längschnittsdatensatz zu zwei Messzeitpunkten, indem jeder Teilnehmer zwei Zeilen hat. Die erste Zeile speichert die die Angaben des Teilnehmenden aus der ersten Befragung und die zweite Zeile speichert die Antworten desselben Teilnehmenden aus der ersten Befragung. Hier ein Beipiel.

Code: Alles auswählen

dat<-data.frame(
"id" = c("A","A","B","B","C","C"),
"time" = c("1", "2","1", "2","1","2")
"gender" = c("male","male","female", "NA","NA","male"))
Es fällt auf, dass nicht jeder Teilnehmer zu jedem Zeitpunkt sein Geschlecht angegeben hat, wodurch es schwierig ist diese bespielhafte Variable als Moderator in Analysen zu verwenden.

Ich würde daher gern eine neue Variable bilden, in der die NAs mit den Angaben aus erster oder zweiter Befragung ausgefüllt werden, jenachdem, an welcher Stelle es angegeben wurde.

Ich habe bereits versucht die ave Funktion zu verwenden, aber da die Variable gender nicht numerisch ist, bekomme ich da eine Fehlermeldung.

Für numerische Variablen haben diese Befehle in der Vergangenheit funktioniert:

Code: Alles auswählen

dat$mod_gender <- ave(dat$gender, dat$id, FUN=function(x) x[1]) 
dat$mod_gender[is.na(dat$mod_gender)] <- ave(dat$gender[is.na(dat$mod_gender)], dat$id, FUN=function(x) x[2]) 
Kann jemand helfen?
bigben
Beiträge: 2778
Registriert: Mi Okt 12, 2016 9:09 am

Re: Neue Spalte mit Daten aus anderen Spalten unter Grouping Bedingungen auffüllen

Beitrag von bigben »

Hallo kosa,

nicht immer ist es gut, wenn Daten "tidy" sind -- wenn man beide Zeitpunkte pro Person in einer Zeile hätte, ein sogenanntes weites Format, dann wird es einfacher, das zusammen zu fassen. Die R-eigenen Mittel dafür sind komisch. Verschiedene packages machen das gut. Zum Beispiel die Funktion pivot_wider() aus dem Paket tidyr oder die Funktion dcast aus dem Paket data.table. Nehmen wir mal letzteres:

Code: Alles auswählen

dat<-data.frame(
  id = c("A", "A","B", "B", "C", "C"),
  time = c("1", "2", "1", "2", "1", "2"),
  gender = c("male", "male", "female", NA, NA, "male"))

library(data.table)
setDT(dat)

gender <- dcast(dat, id ~ time)
print(gender)
#>    id      1    2
#> 1:  A   male male
#> 2:  B female <NA>
#> 3:  C   <NA> male
In dieser Form ist es nun ganz leicht zu schauen, wo die NA sind und die dann durch passende Werte zu ersetzen:

Code: Alles auswählen

gender$gender <- ifelse(is.na(gender$'1'), yes = gender$'2', no = gender$'1')
print(gender)
#>    id      1    2 gender
#> 1:  A   male male   male
#> 2:  B female <NA> female
#> 3:  C   <NA> male   male

Somit haben wir für jede id jetzt einen eindeutigen gender-Eintrag ohne unnötige NA. Das können wir jetzt wieder an dat mergen:

Code: Alles auswählen

# wir brauchen nur die id und die gender-Spalte in gender
gender <- gender[,c("id", "gender")]
# wir brauchen das alte gender in dat nicht mehr
dat <- dat[, -"gender"]

merge(dat, gender, by = "id")
#>    id time gender
#> 1:  A    1   male
#> 2:  A    2   male
#> 3:  B    1 female
#> 4:  B    2 female
#> 5:  C    1   male
#> 6:  C    2   male
Und das war ja das Ziel. Wahrscheinlich nicht der schnellste und einfachste Weg, aber ein sehr logischer und vor allem vielseitiger, mit dem Du alle nur denkbaren Zwischenschritte und Sonderregel umsetzen kannst.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Athomas
Beiträge: 769
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Neue Spalte mit Daten aus anderen Spalten unter Grouping Bedingungen auffüllen

Beitrag von Athomas »

Bitte beachten, dass NA nicht der String "NA" ist!

Wenn wir schon bei data.table sind:

Code: Alles auswählen

library(data.table)

dat <- data.table(
        id     = c("A","A","B","B","C","C"),
        time   = c("1", "2","1", "2","1","2"),
        gender = c("male","male","female", NA,NA,"male")
        )
Auswahl <- function(Vektor) Vektor[!is.na(Vektor)][1]

dat[  , Geschlecht:=Auswahl(gender), by=id]
Damit sammelst Du pro "id" die Werte von "gender" ein, nimmst davon den ersten nicht-NA-Wert und weist den der neuen Variable "Geschlecht" zu.
bigben
Beiträge: 2778
Registriert: Mi Okt 12, 2016 9:09 am

Re: Neue Spalte mit Daten aus anderen Spalten unter Grouping Bedingungen auffüllen

Beitrag von bigben »

Hallo Athomas,

das ist eine sehr elegante Lösung, mit dem
Athomas hat geschrieben: Fr Dez 09, 2022 8:40 amAuswahl <- function(Vektor) Vektor[!is.na(Vektor)][1]
Wieder was gelernt! Danke für's Zeigen,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
jogo
Beiträge: 2086
Registriert: Fr Okt 07, 2016 8:25 am

Re: Neue Spalte mit Daten aus anderen Spalten unter Grouping Bedingungen auffüllen

Beitrag von jogo »

Hallo,

oder auch:

Code: Alles auswählen

Auswahl2 <- function(Vektor) na.omit(Vektor)[1]
Gruß, Jörg
Antworten