9
votes

Datable :: Fread's StringsasFactors = True Argument ne convertit pas les colonnes de caractères en type de facteur - Quelle est la solution de contournement?

Je sais que cette question a été soulevée à plusieurs endroits et j'essaie de trouver une bonne solution possible pendant des heures mais a échoué. C'est pourquoi je demande cela.

Donc, j'ai un énorme fichier de données (~ 5 Go) et j'ai utilisé Fread () pour lire ce xxx

il y a des données manquantes (où il est vide). Dans les données d'origine, il existe de nombreuses colonnes et j'ai donc besoin de trouver un moyen de faire du facteur de colonnes chaque fois que les colonnes incluent des chaînes. Quelqu'un pourrait-il suggérer quelle est la meilleure pratique pour que cela soit fait? J'avais envisagé de le modifier au cadre de données et de faire cela. Mais est-il possible de le faire alors qu'il s'agit d'une donnée de données?


8 commentaires

De ma compréhension, les données.Table ne stocke rien comme facteur par défaut afin de réduire la quantité de stockage. Vous devrez tout changer en facteurs par vous-même. J'ai une ligne de code qui fait cela pour moi: df [ (noms (df)): = Lapply (.sd, as.factor) ,. sdcols = noms (df)] . Edit: Si vous voulez uniquement des colonnes de caractères, utilisez ceci: Types <- data.frame (SAPPLY (DF, classe)); Char_list <- Row.Names (Types) [Types) [Types [[[[1]] == 'caractère']] puis remplacez les noms (df) avec Char_list


@Michal mais les facteurs prennent moins de mémoire pour stocker


Avez-vous essayé spécifier "facteur" si nécessaire dans le COLCLASSES argument sur Fread ?


@Michaelchirico, ce n'est pas la meilleure façon de faire dans mon cas depuis dans les données d'origine que j'ai ~ 70 colonnes.


J'ai fait un petit fichier CSV et je peux confirmer le même comportement où stringsasfactors = true n'entraîne pas de colonnes facteurs. En outre, spécifier colclasses comme facteur ne semble pas fonctionner non plus.


Je viens de mettre en œuvre le StringsasFactors Argument ... s'engagera bientôt et devrait être disponible en 1.9.5. Et sur le cran comme 1.9.6.


@rawr souvent, mais pas toujours. objet.size (as.Factor (échantillon (1: 10,1e2, t))) # 1408 octets vs objet.size (as.character (échantillon (1: 101e2, T))) # 1320 octets . Probablement pertinent: Stackoverflow.com/questions/18304760


@FRANK Bien sûr, on peut trouver un contre-exemple exemple, mais tout ce que j'ai à faire est de changer cela en 1e3 et les facteurs prennent la tête par des ordres de grandeur. De plus, j'ai supposé que, étant donné qu'il s'agissait d'un fil sur la table de données, nous parlerons de plus de 100 numériques (qui prenaient moins de mémoire de toute façon objet.size ('1') - objet.size (1) )


4 Réponses :


0
votes

C'est essentiellement un commentaire, mais c'est long, voilà donc.

Vous pouvez utiliser collasses pour spécifier quelles colonnes sont des facteurs.

si vous " J'ai eu beaucoup de colonnes, quelque chose que j'ai fait pour simplifier est d'utiliser la fonction suivante que j'ai écrite: xxx

dire que vous avez un .csv avec des colonnes de classes: xxx

alors vous pouvez utiliser ma fonction pour définir xxx

ceci permettra d'économiser particulièrement de l'espace Si vous avez de longues chaînes d'un type consécutivement.

(Je sais que ce n'est pas la fonction la plus robuste, mais cela m'a assez bien servi de fois quand il y a beaucoup de champs à lire)


0 commentaires

0
votes

J'ai fait un petit fichier CSV et je peux confirmer le même comportement où StringsasFactors = True n'entraîne pas de colonnes facteurs. En particulier spécifiant les colclasses comme facteur ne semble pas fonctionner non plus.

Si vous exécutez ceci après Fread code> Ça convertir toutes vos colonnes de caractères en facteurs P>

for (j in which(sapply(df, class)=='character')) set(df, i=NULL, j=j, value=as.factor(df[[j]]))


0 commentaires

0
votes

Essayez le nouveau LIVERR Paquet, il a été optimisé pour être 10 fois plus rapide et pas la mémoire de fuite. Au lieu de StringSasFactors, vous pouvez désormais spécifier Col_Types Argument où vous pouvez spécifier un collecteur (Code> (une fonction d'analyse personnalisée). Regardez la documentation, en particulier col_factor / parse_factor . XXX


4 commentaires

@Arun alors peut-être que vous devez procéder à une première passe d'essai pour compiler la liste des niveaux. Éventuellement à l'aide de l'argument de la colonne .


@Arun: Cela semble jolie performante, Hadley a fait une grande réécriture, les gens l'utilisent largement, entendons de la part de l'OP Comment cela fonctionnait ... Oui, il faut un peu d'effort pour spécifier vos niveaux


@Arun: Vous n'avez généralement besoin que de charger les premières lignes pour capturer tous les niveaux de facteur, où dites n ~ 100 000. Il serait bon de poster des numéros de performances en tête de tête pour Readr VS Fread .


@Arun Je ne vois aucun point à nous en discutant plus loin dans le résumé; L'OP peut fournir des détails sur leurs niveaux de facteur. Inférer Tous les niveaux de facteur peuvent être une tâche variée de trivial (état matrimonial, cohorte d'âge, codes postaux, gammes de salaire) à fort à impossible - cela dépend entièrement de leur ensemble de données. En ce qui concerne la performance, voyons l'OP (ou quelqu'un d'autre) publier des chiffres. Base :: Read.csv La mémoire fuite, nous pouvons l'éviter maintenant.



11
votes

Juste implémenté StringsasFactors Argument pour Fread en V 1.9.6 +

de Actualités :

  1. implémenté stringsasfacteurs argument pour Fread () . Lorsque true , les colonnes de caractères sont converties en facteurs. La valeur par défaut est false . Merci à Artem Klevtsov pour le dépôt # 501 et to @ hmi2015 pour Ceci donc post .

0 commentaires