Modifier la classe de facteur à numérique de nombreuses colonnes dans un bloc de données

Quel est le moyen le plus rapide / le meilleur pour transformer un grand nombre de colonnes en nombre à partir du facteur?

J’ai utilisé le code suivant mais il semble avoir réorganisé mes données.

> head(stats[,1:2]) rk team 1 1 Washington Capitals* 2 2 San Jose Sharks* 3 3 Chicago Blackhawks* 4 4 Phoenix Coyotes* 5 5 New Jersey Devils* 6 6 Vancouver Canucks* for(i in c(1,3:ncol(stats))) { stats[,i]  head(stats[,1:2]) rk team 1 2 Washington Capitals* 2 13 San Jose Sharks* 3 24 Chicago Blackhawks* 4 26 Phoenix Coyotes* 5 27 New Jersey Devils* 6 28 Vancouver Canucks* 

Quelle est la meilleure façon de nommer chaque colonne comme dans:

 df$colname <- as.numeric(ds$colname) 

Suite à la réponse de Ramnath, le comportement que vous rencontrez est dû au fait que as.numeric(x) renvoie la représentation numérique interne du facteur x au niveau R. Si vous voulez conserver les nombres qui sont les niveaux du facteur (plutôt que leur représentation interne), vous devez d’abord convertir en caractère via as.character() selon l’exemple de Ramnath.

Votre boucle for est tout aussi raisonnable qu’un appel d’ apply et peut être légèrement plus lisible quant à l’intention du code. Changez simplement cette ligne:

 stats[,i] <- as.numeric(stats[,i]) 

lire

 stats[,i] <- as.numeric(as.character(stats[,i])) 

Ceci est la FAQ 7.10 dans la FAQ R.

HTH

Vous devez faire attention en changeant les facteurs en numérique. Voici une ligne de code qui changerait un ensemble de colonnes de facteur à numérique. Je suppose ici que les colonnes à changer en numérique sont respectivement 1, 3, 4 et 5. Vous pouvez le changer en conséquence

 cols = c(1, 3, 4, 5); df[,cols] = apply(df[,cols], 2, function(x) as.numeric(as.character(x))); 

Cela peut être fait en une seule ligne, il n’y a pas besoin de boucle, que ce soit une boucle ou une application. Utilisez plutôt unlist ():

 # testdata Df <- data.frame( x = as.factor(sample(1:5,30,r=TRUE)), y = as.factor(sample(1:5,30,r=TRUE)), z = as.factor(sample(1:5,30,r=TRUE)), w = as.factor(sample(1:5,30,r=TRUE)) ) ## Df[,c("y","w")] <- as.numeric(as.character(unlist(Df[,c("y","w")]))) str(Df) 

Edit: pour votre code, cela devient:

 id <- c(1,3:ncol(stats))) stats[,id] <- as.numeric(as.character(unlist(stats[,id]))) 

Évidemment, si vous avez un bloc de données à une colonne et que vous ne voulez pas que la réduction automatique de dimension de R le convertisse en un vecteur, vous devez append l'argument drop=FALSE .

Je sais que cette question est résolue depuis longtemps, mais j’ai récemment eu un problème similaire et je pense avoir trouvé une solution un peu plus élégante et fonctionnelle, même si elle nécessite le paquet magrittr.

 library(magrittr) cols = c(1, 3, 4, 5) df[,cols] %<>% lapply(function(x) as.numeric(as.character(x))) 

L’opérateur %<>% canalise et réaffecte, ce qui est très utile pour simplifier le nettoyage et la transformation des données. Maintenant, la fonction d’application de liste est beaucoup plus facile à lire, en spécifiant uniquement la fonction que vous souhaitez appliquer.

Je pense que ucfagls a trouvé pourquoi votre boucle ne fonctionne pas.

Si vous ne voulez toujours pas utiliser une boucle, voici une solution avec lapply :

 factorToNumeric <- function(f) as.numeric(levels(f))[as.integer(f)] cols <- c(1, 3:ncol(stats)) stats[cols] <- lapply(stats[cols], factorToNumeric) 

Modifier. J'ai trouvé une solution plus simple. Il semble que as.masortingx convertisse en caractère. Alors

 stats[cols] <- as.numeric(as.matrix(stats[cols])) 

devrait faire ce que vous voulez.

lapply est à peu près conçu pour cela

 unfactorize<-c("colA","colB") df[,unfactorize]<-lapply(unfactorize, function(x) as.numeric(as.character(df[,x]))) 

J’ai trouvé cette fonction sur deux autres threads en double et je l’ai trouvée élégante et générale pour résoudre ce problème. Ce fil apparaît en premier sur la plupart des recherches sur ce sujet, donc je le partage ici pour gagner du temps. Je ne prends aucun crédit pour cela, alors voyez les articles originaux ici et ici pour plus de détails.

 df <- data.frame(x = 1:10, y = rep(1:2, 5), k = rnorm(10, 5,2), z = rep(c(2010, 2012, 2011, 2010, 1999), 2), j = c(rep(c("a", "b", "c"), 3), "d")) convert.magic <- function(obj, type){ FUN1 <- switch(type, character = as.character, numeric = as.numeric, factor = as.factor) out <- lapply(obj, FUN1) as.data.frame(out) } str(df) str(convert.magic(df, "character")) str(convert.magic(df, "factor")) df[, c("x", "y")] <- convert.magic(df[, c("x", "y")], "factor") 

Je voudrais souligner que si vous avez des NA dans une colonne, utiliser simplement des indices ne fonctionnera pas. S’il y a des AN dans le facteur, vous devez utiliser le script d’application fourni par Ramnath.

Par exemple

 Df <- data.frame( x = c(NA,as.factor(sample(1:5,30,r=T))), y = c(NA,as.factor(sample(1:5,30,r=T))), z = c(NA,as.factor(sample(1:5,30,r=T))), w = c(NA,as.factor(sample(1:5,30,r=T))) ) Df[,c(1:4)] <- as.numeric(as.character(Df[,c(1:4)])) 

Renvoie les éléments suivants:

 Warning message: NAs introduced by coercion > head(Df) xyzw 1 NA NA NA NA 2 NA NA NA NA 3 NA NA NA NA 4 NA NA NA NA 5 NA NA NA NA 6 NA NA NA NA 

Mais:

 Df[,c(1:4)]= apply(Df[,c(1:4)], 2, function(x) as.numeric(as.character(x))) 

Résultats:

 > head(Df) xyzw 1 NA NA NA NA 2 2 3 4 1 3 1 5 3 4 4 2 3 4 1 5 5 3 5 5 6 4 2 4 4 

J’ai eu des problèmes pour convertir toutes les colonnes en numeric avec un appel apply() :

 apply(data, 2, as.numeric) 

Le problème est que certaines chaînes ont une virgule – par exemple “1,024.63” au lieu de “1024.63” – et R n’aime pas cette manière de formater les nombres. Donc je les ai enlevés et puis as.numeric() couru comme as.numeric() :

 data = as.data.frame(apply(data, 2, function(x) { y = str_replace_all(x, ",", "") #remove commas return(as.numeric(y)) #then convert })) 

Notez que cela nécessite le package ssortingngr à charger.

C’est ce qui a fonctionné pour moi. La fonction apply() essaie de forcer df à masortingce et renvoie les NA.

numeric.df <- as.data.frame(sapply(df, 2, as.numeric))

vous pouvez utiliser la fonction unfactor() du formulaire CRAN “varhandle”:

 library("varhandle") my_iris <- data.frame(Sepal.Length = factor(iris$Sepal.Length), sample_id = factor(1:nrow(iris))) my_iris <- unfactor(my_iris)