Importa file di testo come stringa a singolo carattere


204

Come si importa un file di testo semplice come stringa di singolo carattere in R? Penso che probabilmente avrà una risposta molto semplice ma quando ho provato questo oggi ho scoperto che non riuscivo a trovare una funzione per farlo.

Ad esempio, supponiamo di avere un file foo.txtcon qualcosa che voglio textmine.

L'ho provato con:

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

ma questo ha comunque restituito un vettore. Ho funzionato un po 'con:

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

ma questa è una soluzione piuttosto brutta che probabilmente è anche instabile.


20
readr::read_filerisolve bene questo problema ora.
Zach,

Risposte:


213

Ecco una variante della soluzione di @JoshuaUlrich che utilizza la dimensione corretta anziché una dimensione codificata:

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

Si noti che readChar alloca spazio per il numero di byte specificato, quindi readChar(fileName, .Machine$integer.max)non funziona bene ...


18
Vale la pena sottolineare che questo codice non funzionerà per i file compressi. In tal caso, il numero di byte restituiti da file.info (nome file) $ size non corrisponderà al contenuto effettivo che verrà letto in memoria, che prevediamo essere maggiore.
asieira,

146

Nel caso in cui qualcuno stia ancora esaminando questa domanda 3 anni dopo, il pacchetto readr di Hadley Wickham ha una comoda read_file()funzione che lo farà per te.

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

2
Purtroppo "read_file" non appare ora in stringr. :( cran.r-project.org/web/packages/stringr/stringr.pdf
Michael Lloyd Lee mlk

7
@mlk è stato migrato a readr. Ho aggiornato la risposta di conseguenza - spero che a Sharon non dispiaccia.
Nick Kennedy,

1
simpatico ! decomprime anche i file .gz al volo
Andre Holzner,

Ho ottenuto could not find function "pase"questo codice
Sashko Lykhenko,

47

Vorrei usare quanto segue. Dovrebbe funzionare bene e non sembra brutto, almeno per me:

singleString <- paste(readLines("foo.txt"), collapse=" ")

15
Mi sarei aspettato collapse="\n"di replicare il fatto che si tratta di linee separate sul file originale. Con questa modifica, questa soluzione sarà lavoro per i file compressi e non compressi ugualmente bene.
asieira,

Questo non sembra funzionare. Se scrivoLines (singleString), ottengo un file danneggiato ...
bumpkin,

Questo non funziona se l'ultima riga non include un carattere di fine riga. In tal caso, l'ultima riga non è inclusa nella stringa (in alternativa, il file viene troncato all'ultima interruzione di riga).
gvrocha,

Questo funzionerà perfettamente per la lettura di file di testo come nel queston dell'OP: le connessioni ai file di testo sono blocking=TRUEdi default, quindi readLines()restituirà il file completo solo con un avviso sul carattere EOL mancante. Comunque vale il commento di @ gvrocha: fai attenzione al tuo tipo di connessione! ? readLines help diceIf 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


8

Il pacchetto readr ha una funzione per fare tutto per te.

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

Questo sostituisce la versione nel pacchetto stringr.


5

Peccato che la soluzione di Sharon non possa più essere utilizzata. Ho aggiunto la soluzione di Josh O'Brien con la modifica di asieira al mio file .Rprofile:

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

e usarlo in questo modo: txt = read.text('path/to/my/file.txt'). Non sono riuscito a replicare la scoperta di Bumpkin (28 ottobre 14) e ho writeLines(txt)mostrato il contenuto di file.txt. Inoltre, dopo che write(txt, '/tmp/out')il comando diff /tmp/out path/to/my/file.txtnon ha riportato differenze.


2

readChar non ha molta flessibilità, quindi ho combinato le tue soluzioni (readLines e paste).

Ho anche aggiunto uno spazio tra ogni riga:

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

1

Sembra che la tua soluzione non sia molto brutta. Puoi usare le funzioni e renderlo professionale come in questi modi

  • primo modo
new.function <- function(filename){
  readChar(filename, file.info(filename)$size)
}

new.function('foo.txt')
  • secondo modo
new.function <- function(){
  filename <- 'foo.txt'
  return (readChar(filename, file.info(filename)$size))
}

new.function()

1
Questo non aggiunge nulla alla risposta fornita da @Tommy . Fornire il percorso all'interno di un ambiente funzionale è una soluzione particolarmente scadente.
Konrad
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.