ProblèmeConvertir des variables de caractère numérique, mais à l'exclusion d'une variable de caractères
Travailler avec une trame de données en R, je souhaite modifier les variables représentées sous forme de caractères dans les variables représentées sous forme de nombres (ie de la classe chr
-num
).
Pour un ensemble de données complet, c'est un problème simple (saveurs différentes de solutions here, here, here et here). Cependant, j'ai une variable qui doit rester en tant que caractères.
Exemple de données
En utilisant cet exemple des données (df
), disons que je veux changer seulement var1
de la classe chr
-num
, laissant "chrOK"
comme une variable chr
. Dans mon jeu de données réel, il y a beaucoup de variables à changer, donc les approches manuelles comme df$var1 = as.numeric(df$var1)
sont trop laborieuses.
df = data.frame(var1 = c("1","2","3","4"),
var2 = c(1,2,3,4),
chrOK = c("rick", "summer","beth", "morty"),
stringsAsFactors = FALSE)
str(df)
'data.frame': 4 obs. of 3 variables:
$ var1 : chr "1" "2" "3" "4"
$ var2 : num 1 2 3 4
$ chrOK: chr "rick" "summer" "beth" "morty"
Solutions partielles
J'ai essayé plusieurs approches qui semblent proches, mais ne font pas exactement ce que je veux.
Tentative 1 - introduit NAs
La plupart de mes colonnes sont des caractères qui doivent être numériques, comme "var1"
. Donc, en utilisant apply()
pour convertir les travaux de classe. Cependant, cette approche échoue induit NA
valeurs dans "chrOK"
.
df = as.data.frame(apply(df, 2, function(x) as.numeric(x)))
Warning message:
In FUN(newX[, i], ...) : NAs introduced by coercion
str(df)
'data.frame': 4 obs. of 3 variables:
$ var1 : num 1 2 3 4
$ var2 : num 1 2 3 4
$ chrOK: num NA NA NA NA
Tentative 2 - split, convertir, cbind
En utilisant apply()
sur le sous-ensemble de chr
les variables, à l'exclusion "chrOK"
, ne provoque pas NA
s, mais nécessite l'utilisation cbind()
de re-inclure "chrOK"
.
Cette solution n'est pas idéale car les résultats cbind()
sont difficiles à vérifier pour les mutations de données. (De plus, "chrOK"
est retourné comme un facteur utilisant df = cbind(changed,as.character(unchanged))
ne fonctionne pas [a]..)
changed = as.data.frame(apply(df[-(which(colnames(df)=="chrOK"))],2,function(x) as.numeric(x)))
unchanged = (df$chrOK)
df = cbind(changed,unchanged)
str(df)
'data.frame': 4 obs. of 3 variables:
$ var1 : num 1 2 3 4
$ var2 : num 1 2 3 4
$ unchanged: Factor w/ 4 levels "beth","morty",..: 3 4 1 2 #[a]
Tentative 3 - sous-ensemble correct, mais l'erreur lors de la conversion
En utilisant setdiff()
je reçois le sous-ensemble de chr
variables de classe excluant `" chrOK ".
df[setdiff(names(df[sapply(df,is.character)]),"chrOK")]
var1
1 1
2 2
3 3
4 4
Mais en essayant de le brancher dans une fonction de transformation, de sorte que seul le sous-ensemble est modifié chr
-num
renvoie une erreur (voir [b]).
apply(as.numeric(df[setdiff(names(df[sapply(df,is.character)]),"chrOK")]),
2,function(x) as.numeric(x))
Error in apply(as.numeric(df[setdiff(names(df[sapply(df, is.character)]), :
(list) object cannot be coerced to type 'double' #[b]
Questions
- Quelle est la meilleure solution pour convertir une variables de caractère de trame de données numérique, tout en excluant un sous-ensemble spécifié?
- Laquelle de mes tentatives est le bon chemin ou y at-il une meilleure approche?
- [bonus] Quel mécanisme provoque les résultats inattendus en [a] et [b], ci-dessus?
Cela fonctionne! Comment cela "sait" changer var1 mais pas chrOK? – Danielle
@Danielle Le 'type.convert' appelle un code C interne et il vérifie si les éléments sont des nombres ou des caractères avant de les convertir en classes respectives. – akrun
@Danielle Merci pour les commentaires. Vous pouvez également vérifier [ici] (https://stackoverflow.com/help/someone-answers) – akrun