web-dev-qa-db-fra.com

Suppression des espaces d'un ensemble de données dans R

J'ai essayé de supprimer l'espace blanc que j'ai dans un bloc de données (en utilisant R) . Le bloc de données est volumineux (> 1 Go) et comporte plusieurs colonnes contenant des espaces dans chaque entrée de données. 

Existe-t-il un moyen rapide de supprimer l’espace blanc de l’ensemble du bloc de données? J'ai essayé de faire cela sur un sous-ensemble des 10 premières lignes de données en utilisant:

gsub( " ", "", mydata) 

Cela n'a pas semblé fonctionner, bien que R ait renvoyé une sortie que je n'ai pas pu interpréter. 

str_replace( " ", "", mydata)

R a renvoyé 47 avertissements et n'a pas supprimé l'espace blanc.

erase_all(mydata, " ")

R a renvoyé une erreur en indiquant 'Erreur: impossible de trouver la fonction "erase_all"'

J'apprécierais vraiment de l'aide avec ceci car j'ai passé les dernières 24h à essayer de résoudre ce problème. 

Merci!

10

Si je vous ai bien compris, vous souhaitez supprimer tous les espaces blancs du bloc de données, je suppose que le code que vous utilisez permet de supprimer les espaces dans les noms de colonnes. Je pense que vous devriez essayer ceci:

 apply(myData,2,function(x)gsub('\\s+', '',x))

J'espère que ça marche.

Cela retournera une matrice cependant, si vous voulez le changer en trame de données, alors faites:

as.data.frame(apply(myData,2,function(x)gsub('\\s+', '',x)))

EDIT En 2017:

L'utilisation de la fonction sapply et trimws avec both=T peut supprimer les espaces de début et de fin, mais pas l'intérieur. Comme il n'y avait aucune donnée d'entrée fournie par OP, j'ajoute un exemple factice pour produire les résultats.

df <- data.frame(val = c(" abc"," klm","dfsd "),val1 = c("klm ","gdfs","123"),num=1:3,num1=2:4,stringsAsFactors = F)
truth <- sapply(df,is.character)
df1 <- data.frame(cbind(sapply(df[,truth],trimws,which="both"),df[,!truth]))

Sortie :

> df1
   val val1 num num1
1  abc  klm   1    2
2  klm gdfs   2    3
3 dfsd  123   3    4
> str(df1)
'data.frame':   3 obs. of  4 variables:
 $ val : chr  "abc" "klm" "dfsd"
 $ val1: chr  "klm" "gdfs" "123"
 $ num : int  1 2 3
 $ num1: int  2 3 4
16
PKumar

Reprenant Fremzy et le commentaire de Stamper, voici maintenant ma routine pratique pour nettoyer les blancs dans les données:

df <- data.frame(lapply(df, trimws), stringsAsFactors = FALSE)

Comme d'autres l'ont noté, tous les types sont modifiés en caractères. Dans mon travail, je détermine d’abord les types disponibles dans l’original et les conversions requises. Après avoir coupé, je réapplique les types nécessaires.

Si vos types d'origine sont corrects, appliquez la solution de MarkusN ci-dessous https://stackoverflow.com/a/37815274/2200542

Ceux qui travaillent avec des fichiers Excel souhaiteront peut-être explorer le paquet readxl dont la valeur par défaut est trim_ws = TRUE lors de la lecture.

R n’est tout simplement pas le bon outil pour une telle taille de fichier. Cependant avoir 2 options: 

Utilisez ffdply et ff base

Utilisez les packages ff et ffbase:

library(ff)
library(ffabse)
x <- read.csv.ffdf(file=your_file,header=TRUE, VERBOSE=TRUE,
                 first.rows=1e4, next.rows=5e4)
x$split = as.ff(rep(seq(splits),each=nrow(x)/splits))
ffdfdply( x, x$split , BATCHBYTES=0,function(myData)        
             apply(myData,2,function(x)gsub('\\s+', '',x))

Utilisez sed (ma préférence)

sed -ir "s/(\S)\s+(/S)/\1\2/g;s/^\s+//;s/\s+$//" your_file 
3
agstudy

En reprenant Fremzy et Mielniczuk, je suis arrivé à la solution suivante:

data.frame(lapply(df, function(x) if(class(x)=="character") trimws(x) else(x)), stringsAsFactors=F)

Cela fonctionne pour les images mixtes numériques/caractères qui ne manipulent que des colonnes de caractères.

3
MarkusN

Si vous avez affaire à de grands ensembles de données comme celui-ci, vous pourriez vraiment bénéficier de la vitesse de data.table

library(data.table)

setDT(df)

for (j in names(df)) set(df, j = j, value = df[[trimws(j)]]) 

Je m'attendrais à ce que ce soit la solution la plus rapide. Cette ligne de code utilise l'opérateur set de data.table, qui parcourt les colonnes très rapidement. Il y a une bonne explication ici: Boucle rapide avec set .

2
rafa.pereira

Si vous souhaitez conserver les classes de variables dans votre data.frame, sachez que l'utilisation de apply les masquera, car elle génère une matrix où toutes les variables sont converties en character ou numeric. En vous basant sur le code de Fremzy et Anthony Simon Mielniczuk, vous pouvez parcourir les colonnes de votre data.frame et couper l'espace blanc des seules colonnes de classe factor ou character (et conserver vos classes de données):

for (i in names(mydata)) {
  if(class(mydata[, i]) %in% c("factor", "character")){
    mydata[, i] <- trimws(mydata[, i])
  }
}
0
r3robertson