J'ai un cadre de données avec des colonnes de facteurs numériques et ordonnées. J'ai beaucoup de valeurs NA, donc aucun niveau ne leur est assigné. J'ai changé NA en "Pas de réponse", mais les niveaux des colonnes de facteurs ne contiennent pas ce niveau. Voici comment j'ai commencé, mais je ne sais pas comment le terminer de manière élégante:
addNoAnswer = function(df) {
factorOrNot = sapply(df, is.factor)
levelsList = lapply(df[, factorOrNot], levels)
levelsList = lapply(levelsList, function(x) c(x, "No Answer"))
...
Existe-t-il un moyen d'appliquer directement de nouveaux niveaux à des colonnes de facteur, par exemple, par exemple:
df[, factorOrNot] = lapply(df[, factorOrNot], factor, levelsList)
Bien sûr, cela ne fonctionne pas correctement.
Je veux que l'ordre des niveaux soit préservé et que le niveau "Pas de réponse" soit ajouté à la dernière place.
Vous pouvez définir une fonction qui ajoute les niveaux à un facteur, mais ne renvoie rien d'autre:
addNoAnswer <- function(x){
if(is.factor(x)) return(factor(x, levels=c(levels(x), "No Answer")))
return(x)
}
Ensuite, vous venez lapply
cette fonction à vos colonnes
df <- as.data.frame(lapply(df, addNoAnswer))
Cela devrait retourner ce que vous voulez.
La fonction levels
accepte l'appel levels(x) <- value
. Par conséquent, il est très facile d'ajouter différents niveaux:
f1 <- factor(c("a", "a", NA, NA, "b", NA, "a", "c", "a", "c", "b"))
str(f1)
Factor w/ 3 levels "a","b","c": 1 1 NA NA 2 NA 1 3 1 3 ...
levels(f1) <- c(levels(f1),"No Answer")
f1[is.na(f1)] <- "No Answer"
str(f1)
Factor w/ 4 levels "a","b","c","No Answer": 1 1 4 4 2 4 1 3 1 3 ...
Vous pouvez ensuite le boucler autour de toutes les variables dans un data.frame:
f1 <- factor(c("a", "a", NA, NA, "b", NA, "a", "c", "a", "c", "b"))
f2 <- factor(c("c", NA, "b", NA, "b", NA, "c" ,"a", "d", "a", "b"))
f3 <- factor(c(NA, "b", NA, "b", NA, NA, "c", NA, "d" , "e", "a"))
df1 <- data.frame(f1,n1=1:11,f2,f3)
str(df1)
'data.frame': 11 obs. of 4 variables:
$ f1: Factor w/ 3 levels "a","b","c": 1 1 NA NA 2 NA 1 3 1 3 ...
$ n1: int 1 2 3 4 5 6 7 8 9 10 ...
$ f2: Factor w/ 4 levels "a","b","c","d": 3 NA 2 NA 2 NA 3 1 4 1 ...
$ f3: Factor w/ 5 levels "a","b","c","d",..: NA 2 NA 2 NA NA 3 NA 4 5 ...
for(i in 1:ncol(df1)) if(is.factor(df1[,i])) levels(df1[,i]) <- c(levels(df1[,i]),"No Answer")
df1[is.na(df1)] <- "No Answer"
str(df1)
'data.frame': 11 obs. of 4 variables:
$ f1: Factor w/ 4 levels "a","b","c","No Answer": 1 1 4 4 2 4 1 3 1 3 ...
$ n1: int 1 2 3 4 5 6 7 8 9 10 ...
$ f2: Factor w/ 5 levels "a","b","c","d",..: 3 5 2 5 2 5 3 1 4 1 ...
$ f3: Factor w/ 6 levels "a","b","c","d",..: 6 2 6 2 6 6 3 6 4 5 ...
En développant la réponse de ilir et son commentaire, vous pouvez vérifier si une colonne est un facteur et si elle ne contient pas déjà le nouveau niveau, puis ajoutez le niveau et rendez ainsi la fonction ré-exécutable:
addLevel <- function(x, newlevel=NULL) {
if(is.factor(x)) {
if (is.na(match(newlevel, levels(x))))
return(factor(x, levels=c(levels(x), newlevel)))
}
return(x)
}
Vous pouvez ensuite l'appliquer comme ceci:
dataFrame$column <- addLevel(dataFrame$column, "newLevel")
Depuis la dernière réponse à cette question, cela est devenu possible en utilisant fct_explicit_na()
à partir du paquet forcats
. J'ajoute ici l'exemple donné dans la documentation.
f1 <- factor(c("a", "a", NA, NA, "a", "b", NA, "c", "a", "c", "b"))
table(f1)
# f1
# a b c
# 4 2 2
f2 <- forcats::fct_explicit_na(f1)
table(f2)
# f2
# a b c (Missing)
# 4 2 2 3
La valeur par défaut est (Missing)
, mais cela peut être modifié via l'argument na_level
.
Vous devez convertir la colonne en caractère, puis ajouter le nouveau niveau en fonction de la condition, puis enfin convertir la colonne en facteur.
Étapes 1.Premier convertisseur de colonne de facteur en caractère:
df$column2 <- as.character(column2)
2.Ajouter le nouveau niveau
df[df$column1=="XYZ",]column2 <- "new_level"
3. Convertir pour factoriser à nouveau
df$column2 <- as.factor(df$column2)
J'ai une réponse très simple qui peut ne pas répondre directement à votre scénario spécifique, mais constitue un moyen simple de le faire en général
levels(df$column) <- c(levels(df$column), newFactorLevel)
Pour les facteurs, les niveaux sont les valeurs numériques attribuées à chaque valeur unique de la variable de facteur. L'avantage d'utiliser des facteurs est que les variables catégorielles sont meilleures pour les visualisations. La valeur d'origine de la variable factorielle est stockée sous forme de caractère, même s'il s'agit d'un nombre. Donc, pour récupérer la valeur originale, utilisez d’abord la conversion as.character - elle renverra les valeurs de facteur, pas les numéros de niveau qui commencent par zéro. Une fois que vous avez défini la valeur du format de caractère, utilisez as.numeric pour obtenir la valeur numérique d'origine.
factor_var.values = as.numeric (as.character (df $ factor_var))