Importar archivo de texto como cadena de un solo carácter


204

¿Cómo se importa un archivo de texto sin formato como cadena de un solo carácter en R? Creo que esto probablemente tendrá una respuesta muy simple, pero cuando probé esto hoy descubrí que no podía encontrar una función para hacerlo.

Por ejemplo, supongamos que tengo un archivo foo.txtcon algo que quiero minar.

Lo probé con:

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

pero esto todavía devolvió un vector. Lo tengo trabajando un poco con:

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

pero esa es una solución bastante fea que probablemente también sea inestable.


20
readr::read_fileresuelve este problema muy bien ahora.
Zach

Respuestas:


213

Aquí hay una variante de la solución de @JoshuaUlrich que usa el tamaño correcto en lugar de un tamaño codificado:

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

Tenga en cuenta que readChar asigna espacio para la cantidad de bytes que especifique, por lo readChar(fileName, .Machine$integer.max)que no funciona bien ...


18
Vale la pena señalar que este código no funcionará para archivos comprimidos. En ese caso, el número de bytes devueltos por file.info (nombre de archivo) $ size no coincidirá con el contenido real que se leerá en la memoria, que esperamos sea mayor.
asieira

146

En caso de que alguien todavía esté analizando esta pregunta 3 años después, el paquete de lectura de Hadley Wickham tiene una read_file()función útil que lo hará por usted.

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

2
Por desgracia, "read_file" no aparece en stringr ahora. :( cran.r-project.org/web/packages/stringr/stringr.pdf
Michael Lloyd Lee mlk

8
@mlk ha sido migrado a readr. He actualizado la respuesta en consecuencia, espero que a Sharon no le importe.
Nick Kennedy

2
bonito ! también descomprime archivos .gz sobre la marcha
Andre Holzner

Tengo could not find function "pase"en este código
Sashko Lykhenko

47

Yo usaría lo siguiente. Debería funcionar bien, y no me parece feo, al menos para mí:

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

15
Hubiera esperado collapse="\n"replicar el hecho de que estas son líneas separadas en el archivo original. Con este cambio, esta solución va a trabajar para los archivos comprimidos y sin comprimir igualmente bien.
asieira

Esto no parece funcionar. Si escribo líneas (singleString), obtengo un archivo dañado ...
bumpkin

Esto no funciona si la última línea no incluye un carácter de final de línea. En ese caso, la última línea no se incluye en la cadena (alternativamente, el archivo se trunca en el último salto de línea).
gvrocha

Esto funcionará bien para leer archivos de texto como en el queston del OP: las conexiones de archivos de texto son blocking=TRUEpor defecto, por lo readLines()que devolverá el archivo completo solo con una advertencia sobre el carácter EOL faltante. Sin embargo, vale la pena escuchar el comentario de @gvrocha: ¡comprenda su tipo de conexión! ? ayuda de readLines 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

El paquete de lectura tiene una función para hacer todo por usted.

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

Esto reemplaza la versión en el paquete stringr.


5

Lástima que la solución de Sharon ya no se pueda usar. He agregado la solución de Josh O'Brien con la modificación de asieira a mi archivo .Rprofile:

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

y utilizar de esta manera: txt = read.text('path/to/my/file.txt'). No pude replicar el hallazgo de bumpkin (28 oct. 14), y writeLines(txt)mostré el contenido de file.txt. Además, después de que write(txt, '/tmp/out')el comando diff /tmp/out path/to/my/file.txtno informó diferencias.


2

readChar no tiene mucha flexibilidad, por lo que combiné sus soluciones (readLines y paste).

También he agregado un espacio entre cada línea:

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

1

Parece que tu solución no es muy fea. Puede usar funciones y hacerlo profesional de esta manera

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

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

new.function()

1
Esto no agrega nada a la respuesta proporcionada por @Tommy . Proporcionar ruta dentro de un entorno funcional es una solución particularmente pobre.
Konrad el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.