2016-02-29 1 views
0

J'ai rencontré deux problèmes d'écriture de fonctions pour les trames de données. J'obtiens souvent des trames de données avec 2 variables, et je veux les recoder en une seule variable.R: recodage de 2 variables en 1 fonction interne

If V1>0 and V2 <0 then new_variable = "V1>0, V2<0. 

Dans toutes les bases de données, j'ai V1 et V2 ont des noms différents.

problème numéro 1. Je ne sais pas pourquoi test_df $ NouvelleVar, après cette fonction obtenez seulement "C> 0, I> 0"

#Using test FUN on example data frame 
    test_df.afterFUN <- test_fun(test_df, var1 = "V1", var2 = "V2", newVar = "category") 

Problème numéro 2. Pourquoi dernier argument de cette La fonction "newVar" ne change pas le nom en "catégorie"? Si je lance le code de cette fonction monté sur trame de données unique (changement de nom variable et ect.), Il va travailler et me donner ce que je veux (voir test_df2)

rm(list = ls()) 
    library("dplyr") # for filter 
    # Preparing example data frame 
    rama <- rbind(c(-5:20, -20:5), c(-20:5, -5:20)) 
    rama <- t(rama) 
    colnames(rama) <- c("V1", "V2") 
    test_df <- as.data.frame(rama) 

#Test FUN 

test_fun <- function(df, var1, var2, newVar) { 
    df1 <- filter(df, var1 == 0, var2 == 0) 
    df1 <- mutate(df1, newVar = "C=0, I=0") 
    df2 <- filter(df, var1 == 0, var2 > 0) 
    df2 <- mutate(df2, newVar = "C=0, I>0") 
    df3 <- filter(df, var1 == 0, var2 < 0) 
    df3 <- mutate(df3, newVar = "C=0, I<0") 
    df4 <- filter(df, var1 > 0, var2 == 0) 
    df4 <- mutate(df4, newVar = "C>0, I=0") 
    df5 <- filter(df, var1 > 0, var2 > 0) 
    df5 <- mutate(df5, newVar = "C>0, I>0") 
    df6 <- filter(df, var1 > 0, var2 < 0) 
    df6 <- mutate(df6, newVar = "C>0, I<0") 
    df7 <- filter(df, var1 < 0, var2 == 0) 
    df7 <- mutate(df7, newVar = "C<0, I=0") 
    df8 <- filter(df, var1 < 0, var2 > 0) 
    df8 <- mutate(df8, newVar = "C<0, I>0") 
    df9 <- filter(df, var1 < 0, var2 < 0) 
    df9 <- mutate(df9, newVar = "C<0, I<0") 
    df <- rbind(df1, df2, df3, df4, df5, df6, df7, df8, df9) 
    return(df) 
    } 

    #Using test FUN on example data frame 
    test_df.afterFUN <- test_fun(test_df, var1 = "V1", var2 = "V2", newVar = "category") 

    # Procedure outside of funcion fitted to test_df 
    df1 <- filter(test_df, V1 == 0, V2 == 0) 
    df1 <- mutate(df1, newVar = "C=0, I=0") 
    df2 <- filter(test_df, V1 == 0, V2 > 0) 
    df2 <- mutate(df2, newVar = "C=0, I>0") 
    df3 <- filter(test_df, V1 == 0, V2 < 0) 
    df3 <- mutate(df3, newVar = "C=0, I<0") 
    df4 <- filter(test_df, V1 > 0, V2 == 0) 
    df4 <- mutate(df4, newVar = "C>0, I=0") 
    df5 <- filter(test_df, V1 > 0, V2 > 0) 
    df5 <- mutate(df5, newVar = "C>0, I>0") 
    df6 <- filter(test_df, V1 > 0, V2 < 0) 
    df6 <- mutate(df6, newVar = "C>0, I<0") 
    df7 <- filter(test_df, V1 < 0, V2 == 0) 
    df7 <- mutate(df7, newVar = "C<0, I=0") 
    df8 <- filter(test_df, V1 < 0, V2 > 0) 
    df8 <- mutate(df8, newVar = "C<0, I>0") 
    df9 <- filter(test_df, V1 < 0, V2 < 0) 
    df9 <- mutate(df9, newVar = "C<0, I<0") 
    test_df2 <- rbind(df1, df2, df3, df4, df5, df6, df7, df8, df9) 

Répondre

0

Cela peut probablement être écrit plus agréable, mais essayez :

test_fun <- function(df,col1, col2, newVar) { 
    temp <- sapply(df[,c(col1,col2)],function(x) revalue(factor(sign(x)),c("-1"="<0","0"="=0","1"=">0"))) 
    df[,newVar] <- apply(temp, 1, function(y) paste0(col1,y[1],", ",col2,y[2])) 
    df 
} 

head(test_fun(test_df,"V1", "V2", "category")) 
# V1 V2 category 
# 1 -5 -20 V1<0, V2<0 
# 2 -4 -19 V1<0, V2<0 
# 3 -3 -18 V1<0, V2<0 
# 4 -2 -17 V1<0, V2<0 
# 5 -1 -16 V1<0, V2<0 
# 6 0 -15 V1=0, V2<0 

Explication

Nous utilisons sign pour obtenir le signe de chaque numéro dans une colonne (retourne -1, 0 ou 1). Nous réécrivons ensuite ces nombres comme les chaînes "< 0", "= 0" et "> 0" en utilisant revalue(factor),c()). Nous utilisons sapply pour l'appliquer aux deux colonnes de test_df. Cela retourne une matrice de caractères. Nous appliquons ensuite paste à chaque ligne pour obtenir le vecteur de caractère que vous voulez. Enfin, nous affectons ce vecteur à test_df$category.

+0

Merci pour votre réponse. Savez-vous comment mettre cette fonction à l'intérieur funtion, test_fun (test_df, var1 = "V1", var2 = "V2", newVar = "catégorie"), où vous mettez des pareamters de trame de données et de variables? –

+0

Réécrit le code en tant que fonction; vous pouvez ajuster le reste. – Laterow

+0

Merci beaucoup, maintenant je comprends le point :)! –