Importer un fichier texte en tant que chaîne de caractères unique

204

Comment importer un fichier texte brut en tant que chaîne de caractères unique dans R? Je pense que cela aura probablement une réponse très simple, mais quand j'ai essayé cela aujourd'hui, j'ai trouvé que je ne pouvais pas trouver de fonction pour le faire.

Par exemple, supposons que j'ai un fichier foo.txtavec quelque chose que je veux texturer.

Je l'ai essayé avec:

scan("foo.txt", what="character", sep=NULL)

mais cela a quand même renvoyé un vecteur. Je l'ai fait travailler un peu avec:

paste(scan("foo.txt", what="character", sep=" "),collapse=" ")

mais c'est une solution assez laide qui est probablement aussi instable.

Sacha Epskamp
la source
20
readr::read_filerésout bien ce problème maintenant.
Zach

Réponses:

213

Voici une variante de la solution de @JoshuaUlrich qui utilise la taille correcte au lieu d'une taille codée en dur:

fileName <- 'foo.txt'
readChar(fileName, file.info(fileName)$size)

Notez que readChar alloue de l'espace pour le nombre d'octets que vous spécifiez, donc readChar(fileName, .Machine$integer.max)ne fonctionne pas bien ...

Tommy
la source
18
Il convient de souligner que ce code ne fonctionnera pas pour les fichiers compressés. Dans ce cas, le nombre d'octets renvoyés par file.info (nom de fichier) $ size ne correspondra pas au contenu réel qui sera lu en mémoire, ce qui devrait être plus important.
asieira
146

Au cas où quelqu'un se pencherait encore sur cette question 3 ans plus tard, le paquet readr de Hadley Wickham a une read_file()fonction pratique qui le fera pour vous.

install.packages("readr") # you only need to do this one time on your system
library(readr)
mystring <- read_file("path/to/myfile.txt")
Sharon
la source
2
Hélas, "read_file" n'apparaît pas dans stringr maintenant. :( cran.r-project.org/web/packages/stringr/stringr.pdf
Michael Lloyd Lee mlk
8
@mlk vers lequel il a été migré readr. J'ai mis à jour la réponse en conséquence - j'espère que cela ne dérange pas Sharon.
Nick Kennedy
2
agréable ! décompresse également les fichiers .gz à la volée
Andre Holzner
J'ai eu could not find function "pase"ce code
Sashko Lykhenko
47

J'utiliserais ce qui suit. Cela devrait très bien fonctionner, et ne semble pas laid, du moins pour moi:

singleString <- paste(readLines("foo.txt"), collapse=" ")
Josh O'Brien
la source
15
Je m'attendais collapse="\n"à reproduire le fait qu'il s'agit de lignes distinctes dans le fichier d'origine. Avec ce changement, cette solution va travailler pour les fichiers compressés et non compressés tout aussi bien.
asieira
Cela ne semble pas fonctionner. Si j'écris des lignes (singleString), j'obtiens un fichier corrompu ...
bumpkin
Cela ne fonctionne pas si la dernière ligne ne contient pas de caractère de fin de ligne. Dans ce cas, la dernière ligne n'est pas incluse dans la chaîne (en variante, le fichier est tronqué au dernier saut de ligne).
gvrocha
Cela fonctionnera très bien pour la lecture des fichiers texte comme dans le queston de l'OP: Les connexions aux fichiers texte sont blocking=TRUEpar défaut donc readLines()retourneront le fichier complet juste avec un avertissement sur le caractère EOL manquant. Cependant, le commentaire de @ gvrocha mérite d'être entendu: comprenez votre type de connexion! ? L'aide de readLines ditIf the final line is incomplete (no final EOL marker) the behaviour depends on whether the connection is blocking or not. For a non-blocking text-mode connection the incomplete line is pushed back, silently. **For all other connections the line will be accepted, with a warning.**
krads
15

Que diriez-vous:

string <- readChar("foo.txt",nchars=1e6)
Joshua Ulrich
la source
8

Le paquet readr a une fonction pour tout faire pour vous.

install.packages("readr") # you only need to do this one time on your system
library(readr)
mystring <- read_file("path/to/myfile.txt")

Cela remplace la version dans le package stringr.

Mike Stanley
la source
5

Dommage que la solution de Sharon ne puisse plus être utilisée. J'ai ajouté la solution de Josh O'Brien avec la modification de asieira à mon fichier .Rprofile:

read.text = function(pathname)
{
    return (paste(readLines(pathname), collapse="\n"))
}

et l' utiliser comme ceci: txt = read.text('path/to/my/file.txt'). Je n'ai pas pu reproduire les conclusions de Bumpkin (28 oct. 14) et j'ai writeLines(txt)montré le contenu de file.txt. De plus, après write(txt, '/tmp/out')la commande, diff /tmp/out path/to/my/file.txtaucune différence n'a été signalée.

Frank B. Brokken
la source
2

readChar n'a pas beaucoup de flexibilité, j'ai donc combiné vos solutions (readLines et paste).

J'ai également ajouté un espace entre chaque ligne:

con <- file("/Users/YourtextFile.txt", "r", blocking = FALSE)
singleString <- readLines(con) # empty
singleString <- paste(singleString, sep = " ", collapse = " ")
close(con)
harris11
la source
1

Il semble que votre solution ne soit pas très moche. Vous pouvez utiliser des fonctions et le rendre professionnel comme ces façons

  • première voie
new.function <- function(filename){
  readChar(filename, file.info(filename)$size)
}

new.function('foo.txt')
  • deuxième voie
new.function <- function(){
  filename <- 'foo.txt'
  return (readChar(filename, file.info(filename)$size))
}

new.function()
Kalana
la source
1
Cela n'ajoute rien à la réponse fournie par @Tommy . Fournir un chemin dans un environnement fonctionnel est une solution particulièrement mauvaise.
Konrad