2016-08-02 16 views
0

Ich habe einen Datenrahmen mit Spalten mit den Bezeichnungen q1, q2, q3 usw. Ich möchte eine Funktion erstellen, die Argumente (Variablenname, Datenrahmen, Levelvektor, Labelvektor) nimmt und die codierten Antworten in Strings ändert.Warum kann ich den Ladefaktor nicht innerhalb einer Funktion verwenden?

Zum Beispiel, wenn q3 ist 1, 2 oder 3, und ich möchte dies zu "schlecht", "neutral", "gut" UND q4 ist eine Reihe von 4 Spalten (q4r1, q4r2, q4r3 , q4r4) mit kodierten Antworten 1, 2, oder 3, und ich will diejenigen auf "rot", "blau", "grün" ändern:

findCol <- function(vn, df) { 
    if (length(which(grepl(vn, names(df)))) > 1) { 
    which(grepl(vn, names(df))) 
    } else { 
    which(colnames(df)==vn) 
    } 
} 

und

labelChng <- function(cv, df, levs, labs) { 
    if (length(cv) > 1) { 
    df[cv[1]:cv[length(cv)]] <- lapply(df[cv[1]:cv[length(cv)]], factor, 
    levels = levs, labels = labs) 
    } else { 
    df[cv] <- lapply(df[cv], factor, levels = levs, labels = labs) 
    } 
} 

Dann

q3c <- findCol("q3", myData) 
q3lev <- c(1:3) 
q3lab <- c("bad", "neutral", "good") 
q4c <- findCol("q4", myData) 
q4lev <- c(1:3) 
q4lab <- c("red", "blue", "green") 

Die Funktion findCol funktioniert einwandfrei, aber wenn ich versuche, labelChng auszuführen, ändert sich nichts. Als ich dies direkt in der Konsole ausführen:

myData[q4c[1]:q4c[length(q4c)]] <- lapply(myData[q4c[1]:q4c[length(q4c)]], factor, 
levels = q4lev, labels = q4lab) 

funktioniert es ganz gut, aber nicht, wenn ich benutze:

labelChng(q4c, myData, q4lev, q4lab) 

Ich bin neu dies so sein kann offensichtlich etwas fehlt. Jede Rückmeldung hilft.

+0

Die erste Funktion kann abgekürzt werden zu 'findCol <- Funktion (vn, df) welche (grepl (vn, Namen (df)))'? –

+1

Ich glaube, du machst eigentlich keine Veränderung. Das 'df', das Sie in Ihrer 'labelChng'-Funktion bearbeiten, ist nur lokal für diese Funktion. Wenn Sie etwas ändern wollen, sollten Sie eine 'return (df)' –

+1

@MikeyMike verwenden Ich dachte das gleiche –

Antwort

2

Ihre zweite Funktion gibt keinen Wert und kann vereinfacht werden:

#Simplified Helpers 
findCol <- function(vn, df) grepl(vn, names(df)) 

labelChng <- function(cv, df, levs, labs) { 
    df[cv] <- lapply(df[cv], factor, levels=levs, labels=labs) 
    return(df) 
} 

myData <- data.frame(q1=1:3, q2=3:1, q3=2) 
myData 
# q1 q2 q3 
# 1 1 3 2 
# 2 2 2 2 
# 3 3 1 2 


q2c <- findCol('q2', myData) 
q2lev <- c(1:3) 
q2lab <- c("bad", "neutral", "good") 
labelChng(q2c, myData, q2lev, q2lab) 
# q1  q2 q3 
# 1 1 good 2 
# 2 2 neutral 2 
# 3 3  bad 2 
+0

Vielleicht auch erwähnenswert, dass die 'cv [1]: cv [length (cv)]' 'eine schlechte Idee ist. Wenn es sich jemals vom einfachen alten 'cv' unterscheidet, wird es seltsame Dinge tun (das Ändern von Spalten, die das Kriterium grepl nicht erfüllen). – Frank

+1

Oh, ich bin noch nicht in den Shredding geraten. –

+1

Ja - ich sehe das Problem damit jetzt. Vielen Dank! – j8sR

1

Ein weiterer Ansatz ist es, die plyr Paket zu verwenden. Die Plyr-Bibliothek hat zwei nützliche revalue und mapvalues Funktionen, um einen Satz von Faktoren in einen anderen zu konvertieren. Hier ein Beispiel:

library(plyr) 
df<-data.frame(x=1:3) 
df$x<-as.factor(df$x) 
q3lev <- c(1:3) 
q3lab <- c("bad", "neutral", "good") 

df$x<-mapvalues(df$x, from=q3lev, to=q3lab) 
Verwandte Themen