Seite 1 von 1

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

Verfasst: Do Dez 08, 2022 5:07 pm
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?

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

Verfasst: Do Dez 08, 2022 9:57 pm
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

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

Verfasst: Fr Dez 09, 2022 8:40 am
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.

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

Verfasst: Fr Dez 09, 2022 1:31 pm
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

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

Verfasst: Di Dez 13, 2022 11:25 am
von jogo
Hallo,

oder auch:

Code: Alles auswählen

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