J'ai un fichier délimité | désordonné que je veux nettoyer. Une bonne ligne ressemble à ceci:
data <- read_delim("myfile.txt", delim = "|")
data <- data[, c(-1, -3, -5)] #to remove the columns just containing commas
Et plusieurs lignes en désordre qui ont des sauts de ligne là où ils n'appartiennent pas
10,|some data|,|lots of text blah blah blah blah and more text sometimes text stretches across many lines|,|some numbers|
Comme indiqué, le le nombre de colonnes est théoriquement le même mais les données sont désordonnées de telle sorte qu'il y a des sauts de ligne là où ils ne devraient pas être.
Je voudrais lire dans le fichier afin que les valeurs entre | sont tous stockés dans le même vecteur (dans un dataframe).
Je lis actuellement dans le fichier en utilisant
1,|some data|,|more data|,|some numbers|
Mais cela me donne beaucoup de mal lignes analysées.
Je pensais dire à R d'une manière ou d'une autre que je voudrais supprimer tous les sauts de ligne avant le 6ème |. Des idées sur la façon de faire cela ou comment lire dans ce fichier désordonné d'une autre manière?
Je dois ajouter que le fichier est très volumineux et que le rangement manuel n'est pas une option.
p>
3 Réponses :
Vos données semblent suivre quelques modèles:
, | ou |,| | \ n (barre suivie d'une nouvelle ligne) \ n peut apparaître aléatoirement au milieu de la colonne Si vous pouvez identifier de tels modèles, vous pouvez traiter le fichier étape par étape afin de le faire passer au format csv le plus courant:
V1 V2 V3 V4 1 1 some data more data some numbers 2 10 some data lots of text blah blah blah blah and more text sometimes text stretches across many lines some numbers 3 10 some data lots of text blah blah blah blah and more text sometimes text stretches across many lines some numbers 4 1 some data more data some numbers
En utilisant ce pipeline, nous pouvons passer d'un fichier qui ressemble à ceci:
1,|some data|,|more data|,|some numbers| 10,|some data|,|lots of text blah blah blah blah and more text sometimes text stretches across many lines|,|some numbers| 10,|some data|,|lots of text blah blah blah blah and more text sometimes text stretches across many lines|,|some numbers| 1,|some data|,|more data|,|some numbers|
Vers le bloc de données suivant:
library(dplyr)
data <- readr::read_file("file.txt") %>% # read the file as a string
str_replace_all(",\\||\\|,\\|", ",") %>% # replace all column separators with commas
str_replace_all("\n", "") %>% # replace all newlines with empty strings
str_replace_all("\\|", "\n") %>% # replace all remaining bars with newlines
read.csv(text = ., header = FALSE) # read the .csv string into a data frame
read_delim ("file.txt", delim = ",", quote = "|", col_names = F) fonctionnerait-il également? Je viens de lire quelque part que c'est une façon de lire ces fichiers.
@TeaTree ouais, ça semble marcher! Quelle solution magnifiquement concise.
En suivant l'idée de @ thelatemale, nous pourrions utiliser readLines et réduire en une seule chaîne en utilisant paste .
Ensuite, nous appliquons strsplit deux fois . Tout d'abord, diviser la chaîne à ses numéros de ligne (ils se perdent mais je suppose qu'ils sont consécutifs). Deuxièmement, divisez les chaînes de la liste en |, | et nettoyez un peu en utilisant trinws . Enfin, rbind la chose.
1,|some data|,|more data|,|some numbers| 2,|some data|,|more data|,|some numbers| 3,|some data|,|more data|,|some numbers| 4,|some data|,|lots of text blah blah blah blah and more text sometimes text stretches across many lines|,|some numbers| 5,|some data|,|more data|,|some numbers| 6,|some data|,|lots of text blah blah blah blah and more text, this time with comma, sometimes text stretches across many lines|,|some numbers| 7,|some data|,|more data|,|some numbers| 8,|some data|,|lots of text blah blah blah blah and more text sometimes text stretches across many lines|,|some numbers| 9,|some data|,|more data|,|some numbers| 10,|some data|,|more data|,|some numbers|
# res # V1 V2 V3 # 1 some data more data some numbers # 2 some data more data some numbers # 3 some data more data some numbers # 4 some data lots of text blah blah blah blah and more text sometimes text stretches across many lines some numbers # 5 some data more data some numbers # 6 some data lots of text blah blah blah blah and more text, this time with comma, sometimes text stretches across many lines some numbers # 7 some data more data some numbers # 8 some data lots of text blah blah blah blah and more text sometimes text stretches across many lines some numbers # 9 some data more data some numbers # 10 some data more data some numbers
messy.txt
txt <- paste(readLines(con="R/messy.txt"), collapse=" ") rr <- el(strsplit(txt, "\\b\\d*\\,\\|"))[-1] rr <- strsplit(trimws(rr, whitespace="[\\|| ]"), "|,|", fixed=TRUE) res <- as.data.frame(do.call(rbind, rr))
La solution la plus simple semble être
# X1 X2 X3 X4 # 1 some data more data some numbers # 2 some data lots of text blah blah blah blah and more text sometimes text stretches across many lines some numbers
Où quote indique à read_delim le début et la fin du vecteur même lorsqu'il dépasse plusieurs lignes dans le fichier source. L'argument delim spécifie que les chaînes indiquées par | sont séparés par des virgules.
Cela fonctionne également avec read.delim
1,|some data|,|more data|,|some numbers| 2,|some data|,|lots of text blah blah blah blah and more text sometimes text stretches across many lines|,|some numbers|
et avec data.table fread de / code> pour la vitesse maximale
library(data.table)
fread("file.txt", sep = ",", quote = "|", header = F)
Données
file.txt
read.delim("file.txt", sep = ",", quote = "|", header = F)
Résultat
library(readr)
read_delim("file.txt", delim = ",", quote = "|", col_names = F)
p >
Cela fonctionne-t-il également avec l'ancien read.delim ?
De quelle taille parle-t-on? Pouvez-vous lire tout le texte puis effectuer un remplacement de texte, ou est-ce trop volumineux? par exemple.
txt <- paste (readLines ("filename.txt", collapse = "\ n"); read.table (text = gsub ("[^ |] \ n", "", txt), sep = " | ")Le fichier fait environ 500 Mo ou environ 3,2 millions de lignes (y compris les lignes en désordre).