For loop über Variablen

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

Moderatoren: EDi, jogo

Antworten
JuFl
Beiträge: 2
Registriert: Fr Jul 23, 2021 3:34 pm

For loop über Variablen

Beitrag von JuFl »

Hallo
ich möchte einen for loop über mehrere numerische Variablen laufen lassen, und mit diesem Loop für jede dieser Variablen eine neue kategorielle Variable erstellen. Die Anzahl der Kategorien ist jeweils abhängig von der Anzahl der Beobachtungen > 0 der jeweiligen Variable. Bisher habe ich für jede der Variablen eine eigene if ... else Bedingung verwendet. Da es sich um mehr als 30 Variablen handelt, sollte es mit einem Loop vereinfacht werden. Die Namen meiner Variablen sind nicht numerisch, sondern characters (die Variablen heissen "ABH", "ADH", "AIK", etc.).
Die if... else Bedingungen sehen derzeit so aus:

Code: Alles auswählen

# transform ABH into categorical variable 
if (nrow(subset(Step1.1, Step1.1$ABH != 0)) > 10000) {ABH_Kat <- cut(Step1.1$ABH, breaks=c(0, quantile(subset(Step1.1, Step1.1$ABH != 0)$ABH, probs=seq(from=0, to=1, by=0.1))+1),labels=c("0","1","2","3","4","5","6","7","8","9","10"), right = FALSE)} else if (nrow(subset(Step1.1, Step1.1$ABH != 0)) > 1000) {ABH_Kat <- cut(Step1.1$ABH, breaks=c(0, quantile(subset(Step1.1, Step1.1$ABH != 0)$ABH, probs=seq(from=0, to=1, by=0.25))+1),labels=c("0", "1","2","3","4"), right = FALSE)} else {ABH_Kat <- cut(Step1.1$ABH, breaks=c(0, quantile(subset(Step1.1, Step1.1$ABH != 0)$ABH, probs=seq(from=0, to=1, by=0.5))+1),labels=c("0","1","2"), right = FALSE)} 
ABH_Kat[is.na(ABH_Kat)] <- 0

# transform ADH into categorical variable
if (nrow(subset(Step1.1, Step1.1$ADH != 0)) > 10000) {ADH_Kat <- cut(Step1.1$ADH, breaks=c(0, quantile(subset(Step1.1, Step1.1$ADH != 0)$ADH, probs=seq(from=0, to=1, by=0.1))+1),labels=c("0","1","2","3","4","5","6","7","8","9","10"), right = FALSE)} else if (nrow(subset(Step1.1, Step1.1$ADH != 0)) > 1000) {ADH_Kat <- cut(Step1.1$ADH, breaks=c(0, quantile(subset(Step1.1, Step1.1$ADH != 0)$ADH, probs=seq(from=0, to=1, by=0.25))+1),labels=c("0","1","2","3","4"), right = FALSE)} else {ADH_Kat <- cut(Step1.1$ADH, breaks=c(0, quantile(subset(Step1.1, Step1.1$ADH != 0)$ADH, probs=seq(from=0, to=1, by=0.5))+1),labels=c("0","1","2"), right = FALSE)}
ADH_Kat[is.na(ADH_Kat)] <- 0

# transform AIK into categorical variable
if (nrow(subset(Step1.1, Step1.1$AIK != 0)) > 10000) {AIK_Kat <- cut(Step1.1$AIK, breaks=c(0, quantile(subset(Step1.1, Step1.1$AIK != 0)$AIK, probs=seq(from=0, to=1, by=0.1))+1),labels=c("0","1","2","3","4","5","6","7","8","9","10"), right = FALSE)} else if (nrow(subset(Step1.1, Step1.1$AIK != 0)) > 1000) {AIK_Kat <- cut(Step1.1$AIK, breaks=c(0, quantile(subset(Step1.1, Step1.1$AIK != 0)$AIK, probs=seq(from=0, to=1, by=0.25))+1),labels=c("0","1","2","3","4"), right = FALSE)} else {AIK_Kat <- cut(Step1.1$AIK, breaks=c(0, quantile(subset(Step1.1, Step1.1$AIK != 0)$AIK, probs=seq(from=0, to=1, by=0.5))+1),labels=c("0","1","2"), right = FALSE)}
AIK_Kat[is.na(AIK_Kat)] <- 0
usw.

Wie kann ich daraus einen Loop machen? Das funktioniert aber leider nicht.

Probiert habe ich es so:

Code: Alles auswählen

PCGs <- c("ABH", "ADH", "AIK", "ALZ", "AST", "BSR", "CAR", "COP", "DEP", "DM1", "DM2", "EPI", "GLA", "HCH", "HIV", "hyp", "KHO", "KRE", "KRK", "MCR", "MSK", "NIE", "PAH", "PAR", "PSO", "PSY", "RHE", "SMC", "SMN", "THY", "TRA", "WAS", "ZFP", "ZNS")
for (PCG in PCGs){
  if (nrow(subset(Step1.1, Step1.1$PCG != 0)) > 10000) {
  Kat[PCG] <- cut(Step1.1$PCG, breaks=c(0, quantile(subset(Step1.1, Step1.1$PCG != 0)$PCG, probs=seq(from=0, to=1, by=0.1))+1),labels=c("0","1","2","3","4","5","6","7","8","9","10"), right = FALSE)
} else if (nrow(subset(Step1.1, Step1.1$PCG != 0)) > 1000) {
  Kat[PCG] <- cut(Step1.1$PCG, breaks=c(0, quantile(subset(Step1.1, Step1.1$PCG != 0)$PCG, probs=seq(from=0, to=1, by=0.25))+1),labels=c("0", "1","2","3","4"), right = FALSE)
} else {
  Kat[PCG] <- cut(Step1.1$PCG, breaks=c(0, quantile(subset(Step1.1, Step1.1$PCG != 0)$PCG, probs=seq(from=0, to=1, by=0.5))+1),labels=c("0","1","2"), right = FALSE)} 
  Kat[PCG][is.na(PCG_Kat)] <- 0 
}
Vielen Dank im Voraus.
JuFl
Athomas
Beiträge: 768
Registriert: Mo Feb 26, 2018 8:19 pm

Re: For loop über Variablen

Beitrag von Athomas »

Ich würde eine Funktion schreiben, die das Gewünschte in Bezug auf einen einzelnen Vektor leistet, und die dann mit data.table und lapply (ähnlich wie in https://stackoverflow.com/questions/168 ... by-referen) auf die "große" Datei loslassen (ich versuche mich im EDi-Style :lol: ) ...
JuFl
Beiträge: 2
Registriert: Fr Jul 23, 2021 3:34 pm

Re: For loop über Variablen

Beitrag von JuFl »

Hallo lieber Helfer
Vielen Dank für den Tipp. Ich bin R-Anfänger. Könntest Du mir noch etwas mehr auf die Sprünge helfen? Ersetzt das den for loop oder lasse ich den loop mit dem Vector laufen? Wie sieht die Funktion für den Vector aus?
Herzlichen Dank
JuFl
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: For loop über Variablen

Beitrag von bigben »

Hallo JuFl,

Dein Spaghetticode da oben ist bei mir mehrere Bildschirmbreiten weit, schlecht strukturiert und wahrscheinlich schon in Kenntnis seines Zwecks kaum lesbar. Ich werde das nicht lesen um zu versuchen, einen Zweck zu erraten, den Du uns vorbehälst.

Sagen wir einfach, es gibt eine Funktion, die aus einer numerischen Spalte im Datenframe einen Faktor macht, und weil die mir zu kompliziert ist, versuchen wir es erstmals mit einer ganz einfachen. Sagen wir, sie soll kategorisiere heißen und vorläufig so aussehen:

Code: Alles auswählen

kategorisiere <- function(spalte){
  return(as.factor(spalte))
}
Die musst Du dann halt später mit Sinn füllen.

So, nun brauchen wir ein paar Beispieldaten. In Zukunft werden wir Dich bitten, selbst Beispieldaten zur Verfügung zu stellen. Der älteste Thread im FAQ-Unterforum erklärt verschiedene Wege wie das geht. Für den Moment nehmen wir meine Daten wie folgt:

Code: Alles auswählen

Step <- data.frame(ABH = c(0,0,0,0,0,1,0,2,0,3,0,1,0,1),
                   ADH = c(1,1,1,1,1,1,1,1,1,1,1,1,1,1),
                   AIK = c(0,0,0,0,0,0,0,0,0,0,0,0,0,0))

namen <- names(Step)
Damit enthält Step alle Daten und in namen sind die Namen all der Spalten in Step für die wir kategoriale Schwesterspalten erstellen wollen.

Dafür schaffe ich mir jetzt eine Funktion, die den Namen das Dataframes und die Namen der zu bearbeitenden Spalten als Argument annimmt:

Code: Alles auswählen

myfunc <- function(daten, spalten){
  for(spalte in spalten){
    daten[[ncol(daten)+1]] <- kategorisiere(daten[[spalte]])
    names(daten[spalte]) <- paste0(spalte, "_Kat")
  }
  return(daten)
}
Du erkennst eine for-Schleife, dein "loop", in der jede dieser Spalten das Dataframes der Reihe nach ausgewählt, an kategorisiere übergeben und in geeigneter Weise an den Dataframe angehängt wird. Wir können das einmal ausprobieren:

Code: Alles auswählen

ausprobieren <- myfunc(Step, namen)
print(ausprobieren)
So, ich hoffe das läuft bei Dir und ist übersichtlich genug. Was Du jetzt machen musst ist eine Funktion kategorisiere schreiben, die Deine gestuften cut-Aufrufe für eine Spalte spalte leistet, dann lässt sich das mit myfunc auf beliebig viele Spalten nacheinander anwenden.

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