J'ai un problème avec data.table: comment convertir des classes de colonnes? Voici un exemple simple: Avec data.frame je n'ai pas de problème à le convertir, avec data.table je ne sais pas comment:
df <- data.frame(ID=c(rep("A", 5), rep("B",5)), Quarter=c(1:5, 1:5), value=rnorm(10))
#One way: http://stackoverflow.com/questions/2851015/r-convert-data-frame-columns-from-factors-to-characters
df <- data.frame(lapply(df, as.character), stringsAsFactors=FALSE)
#Another way
df[, "value"] <- as.numeric(df[, "value"])
library(data.table)
dt <- data.table(ID=c(rep("A", 5), rep("B",5)), Quarter=c(1:5, 1:5), value=rnorm(10))
dt <- data.table(lapply(dt, as.character), stringsAsFactors=FALSE)
#Error in rep("", ncol(xi)) : invalid 'times' argument
#Produces error, does data.table not have the option stringsAsFactors?
dt[, "ID", with=FALSE] <- as.character(dt[, "ID", with=FALSE])
#Produces error: Error in `[<-.data.table`(`*tmp*`, , "ID", with = FALSE, value = "c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2)") :
#unused argument(s) (with = FALSE)
Est-ce que je rate quelque chose d'évident ici?
Mise à jour due à la publication de Matthew: J'ai utilisé une version plus ancienne avant, mais même après la mise à jour vers la 1.6.6 (la version que j'utilise maintenant), j'obtiens toujours une erreur.
Mise à jour 2: Disons que je veux convertir chaque colonne de classe "facteur" en colonne "caractère", mais je ne sais pas à l'avance quelle colonne appartient à quelle classe. Avec un data.frame, je peux faire ce qui suit:
classes <- as.character(sapply(df, class))
colClasses <- which(classes=="factor")
df[, colClasses] <- sapply(df[, colClasses], as.character)
Puis-je faire quelque chose de similaire avec data.table?
Mise à jour 3:
sessionInfo () R version 2.13.1 (08/07/2011) Plate-forme: x86_64-pc-mingw32 / x64 (64 bits)
locale:
[1] C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] data.table_1.6.6
loaded via a namespace (and not attached):
[1] tools_2.13.1
la source
data.table
méthodes sont différents de ce qu'ils sont pourdata.frame
#Produces error
. +1 de toute façon. Je n'obtiens aucune erreur, quelle version avez-vous? Il y a un problème dans ce domaine cependant, il a déjà été soulevé, FR # 1224 et FR # 1493 sont une priorité élevée à résoudre. La réponse d'Andrie est cependant le meilleur moyen.invalid times argument
erreur? Fonctionne bien pour moi. Quelle version avez-vous?Réponses:
Pour une seule colonne:
Utilisation
lapply
etas.character
:la source
convcols
de caractères de colonnes.dt[,lapply(.SD,as.numeric),.SDcols=convcols]
est presque instantané alors qu'ildt[,convcols:=lapply(.SD,as.numeric),.SDcols=convcols]
gèle presque R, donc je suppose que je le fais mal. Merciset()
par exemplefor (col in names_factors) set(dt, j=col, value=as.factor(dt[[col]]))
[end quote]Essaye ça
la source
Filter
fonction pour identifier les colonnes, par exemple:changeCols<- names(Filter(is.character, DT))
changeCols <- names(DT)[sapply(DT, is.character)]
.En soulevant le commentaire de Matt Dowle sur la réponse de Geneorama ( https://stackoverflow.com/a/20808945/4241780 ) pour le rendre plus évident (comme encouragé), vous pouvez utiliser
for(...)set(...)
.Créé le 2020-02-12 par le package reprex (v0.3.0)
Voir un autre des commentaires de Matt à https://stackoverflow.com/a/33000778/4241780 pour plus d'informations.
Éditer.
Comme noté par Espen et dans
help(set)
,j
peut être "Nom (s) de colonne (caractère) ou numéro (s) (entier) à attribuer une valeur lorsque la ou les colonnes existent déjà". Celanames_factors <- c(1L, 3L)
fonctionnera également.la source
names_factors
trouve ici. Je suppose que c'est tiré de stackoverflow.com/a/20808945/1666063, donc c'estnames_factors = c('fac1', 'fac2')
dans ce cas - qui sont les noms de colonnes, mais cela pourrait aussi être des numéros de colonne par exemple 1; ncol (dt) qui convertirait toutes les colonnesC'est une mauvaise façon de le faire! Je ne laisse cette réponse qu'au cas où cela résoudrait d'autres problèmes étranges. Ces meilleures méthodes sont probablement en partie le résultat de versions plus récentes de data.table ... il vaut donc la peine de documenter cette manière difficile. De plus, c'est un bel exemple de
eval
substitute
syntaxe pour la syntaxe.qui te donne
la source
set()
par exemplefor (col in names_factors) set(dt, j=col, value=as.factor(dt[[col]]))
set
c'est plus approprié.for(...)set(...)
ici: stackoverflow.com/a/33000778/403310J'ai essayé plusieurs approches.
, ou autrement
la source
Je propose un moyen plus général et plus sûr de faire ces choses,
La fonction
..
s'assure que nous obtenons une variable hors de la portée de data.table; set_colclass définira les classes de vos cols. Vous pouvez l'utiliser comme ceci:la source
Si vous avez une liste de noms de colonnes dans data.table, vous souhaitez changer la classe de do:
la source
dt[, c(convert_to_character) := lapply(.SD, as.character), .SDcols=convert_to_character]
Faites simplement pour attribuer par référence, plutôt que d'utiliser l'attribution plus lente de data.frame.essayer:
la source