Zaimportuj plik tekstowy jako ciąg znaków


204

Jak zaimportować zwykły plik tekstowy jako ciąg jednego znaku w R? Myślę, że prawdopodobnie będzie to bardzo prosta odpowiedź, ale kiedy spróbowałem tego dzisiaj, stwierdziłem, że nie mogę znaleźć funkcji, która by to zrobiła.

Załóżmy na przykład, że mam plik foo.txtz czymś, co chcę wysłać SMS-em.

Próbowałem z:

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

ale to wciąż zwróciło wektor. Mam trochę pracy z:

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

ale jest to dość brzydkie rozwiązanie, które prawdopodobnie również jest niestabilne.


20
readr::read_fileładnie rozwiązuje ten problem.
Zach.

Odpowiedzi:


213

Oto wariant rozwiązania @JoshuaUlrich, który używa poprawnego rozmiaru zamiast rozmiaru zakodowanego na stałe:

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

Pamiętaj, że readChar przydziela miejsce dla określonej liczby bajtów, więc readChar(fileName, .Machine$integer.max)nie działa dobrze ...


18
Warto zauważyć, że ten kod nie działa w przypadku plików skompresowanych. W takim przypadku liczba bajtów zwróconych przez file.info (nazwa pliku) $ size nie będzie zgodna z rzeczywistą zawartością, która zostanie odczytana w pamięci, która naszym zdaniem będzie większa.
asieira

146

W przypadku, gdy ktoś nadal patrzy na to pytanie 3 lata później, pakiet czytnika Hadley Wickham ma przydatną read_file()funkcję, która zrobi to za Ciebie.

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

2
Niestety, „read_file” nie pojawia się teraz w stringr. :( cran.r-project.org/web/packages/stringr/stringr.pdf
Michael Lloyd Lee mlk

7
@mlk zostało przeniesione do readr. Odpowiednio zaktualizowałem odpowiedź - mam nadzieję, że Sharon nie ma nic przeciwko.
Nick Kennedy

1
miły ! również dekompresuje pliki .gz w locie
Andre Holzner

Mam could not find function "pase"ten kod
Sashko Lykhenko

47

Użyłbym następujących. Powinno działać dobrze i przynajmniej nie wydaje mi się brzydkie:

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

15
Spodziewałbym collapse="\n"się powtórzyć fakt, że są to osobne wiersze oryginalnego pliku. Dzięki tej zmianie to rozwiązanie będzie działać równie dobrze dla skompresowanych i nieskompresowanych plików.
asieira

To nie działa. Jeśli napiszę linie (singleString), otrzymam uszkodzony plik ...
bumpkin

To nie działa, jeśli ostatni wiersz nie zawiera znaku końca linii. W takim przypadku ostatni wiersz nie jest zawarty w ciągu (alternatywnie plik jest obcinany przy ostatniej linii).
gvrocha

Będzie to działało poprawnie przy odczytywaniu plików tekstowych, tak jak w pytaniu PO: blocking=TRUEDomyślnie połączenia plików tekstowych, więc readLines()zwróci pełny plik tylko z ostrzeżeniem o brakującym znaku EOL. Jednak komentarz @ gvrocha jest wart uwagi: zrozum typ połączenia! Pomoc readLines mówiIf 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

Pakiet readr ma funkcję, która zrobi wszystko za Ciebie.

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

Zastępuje to wersję w pakiecie stringr.


5

Szkoda, że ​​nie można już użyć rozwiązania Sharon. Dodałem rozwiązanie Josha O'Briena z modyfikacją asieiry do mojego pliku .Rprofile:

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

i używać go tak: txt = read.text('path/to/my/file.txt'). Nie mogłem powtórzyć znaleziska bumpkina (28 października 14) i writeLines(txt)pokazałem zawartość file.txt. Ponadto po write(txt, '/tmp/out')poleceniu diff /tmp/out path/to/my/file.txtnie zgłoszono żadnych różnic.


2

readChar nie ma dużej elastyczności, więc połączyłem twoje rozwiązania (readLines i wklej).

Dodałem również spację między każdą linią:

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

1

Wygląda na to, że twoje rozwiązanie nie jest zbyt brzydkie. Możesz korzystać z funkcji i uczynić go profesjonalnym w taki sposób

  • pierwszy sposób
new.function <- function(filename){
  readChar(filename, file.info(filename)$size)
}

new.function('foo.txt')
  • drugi sposób
new.function <- function(){
  filename <- 'foo.txt'
  return (readChar(filename, file.info(filename)$size))
}

new.function()

1
Nie dodaje to niczego do odpowiedzi udzielonej przez @Tommy . Zapewnienie ścieżki w środowisku funkcji jest szczególnie złym rozwiązaniem.
Konrad,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.