Імпортуйте текстовий файл у вигляді одного символьного рядка


204

Як ви імпортуєте звичайний текстовий файл як єдиний рядок символів у R? Я думаю, що на це, мабуть, буде дуже проста відповідь, але коли я спробував це сьогодні, я виявив, що не можу знайти функцію для цього.

Наприклад, припустимо, у мене є файл foo.txtіз тим, що я хочу передати текстовим файлом.

Я спробував це:

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

але це все-таки повернуло вектор. У мене це працює дещо з:

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

але це досить потворне рішення, яке, мабуть, теж нестабільне.


20
readr::read_fileвирішує цю проблему зараз чудово.
Зак

Відповіді:


213

Ось варіант рішення від @JoshuaUlrich, який використовує правильний розмір замість жорстко закодованого розміру:

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

Зауважте, що readChar виділяє простір для вказаної вами кількості байтів, тому readChar(fileName, .Machine$integer.max)не працює добре ...


18
Варто зазначити, що цей код не буде працювати для стислих файлів. У цьому випадку кількість байтів, повернених файлом.info (ім'я файлу) $ розмір, не буде відповідати фактичному вмісту, який буде прочитаний в пам'яті, який, як ми очікуємо, буде більшим.
asieira

146

У випадку, якщо хтось все ще розглядає це питання через 3 роки, пакет читачів Хедлі Вікхема має зручну read_file()функцію, яка зробить це за вас.

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

2
На жаль, "read_file" зараз не відображається в stringr. :( cran.r-project.org/web/packages/stringr/stringr.pdf
Майкл Ллойд Лі млк

7
@mlk він був перенесений в readr. Відповідно я оновив відповідь - сподіваюся, Шарон не проти.
Нік Кеннеді

1
приємно! також розгортає файли .gz на льоту
Андре Хольцнер

Я потрапив could not find function "pase"на цей код
Сашко Лихченко

47

Я б використав наступне. Це повинно працювати чудово, і, принаймні, мені не здається негарним:

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

15
Я б очікував collapse="\n"повторити той факт, що це окремі рядки у вихідному файлі. З цією зміною це рішення буде однаково добре працювати для стислих і нестиснених файлів.
asieira

Це, здається, не працює. Якщо я пишуЛінії (singleString), я отримую пошкоджений файл ...
bumpkin

Це не працює, якщо останній рядок не містить символу кінця рядка. У цьому випадку останній рядок не включається до рядка (як альтернатива, файл обрізається в останньому розриві рядка).
gvrocha

Це буде добре працювати з читанням текстових файлів, як у квестоні ОП: З'єднання текстових файлів blocking=TRUEза замовчуванням, тому readLines()поверне повний файл лише з попередженням про відсутність символу EOL. Однак до коментаря @ gvrocha варто прислухатися: зрозумійте свій тип підключення! "Довідка readLines кажеIf 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

У пакеті читання є функція, щоб зробити все за вас.

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

Це замінює версію пакета stringr.


5

Шкода, що рішення Шарона більше не можна використовувати. До свого файлу .Rprofile я додав рішення Джоша О'Браєна з модифікацією Ассейри:

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

і використовувати його як це: txt = read.text('path/to/my/file.txt'). Я не зміг повторити висновок бумпкіна (28 жовтня 14) і writeLines(txt)показав вміст file.txt. Крім того, після того, як write(txt, '/tmp/out')команда diff /tmp/out path/to/my/file.txtповідомила про відсутність відмінностей.


2

readChar не має великої гнучкості, тому я поєднав ваші рішення (readLines та вставити).

Я також додав пробіл між кожним рядком:

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

1

Здається, ваше рішення не дуже потворне. Ви можете використовувати функції та робити їх професійними, як ці способи

  • Перший шлях
new.function <- function(filename){
  readChar(filename, file.info(filename)$size)
}

new.function('foo.txt')
  • другий спосіб
new.function <- function(){
  filename <- 'foo.txt'
  return (readChar(filename, file.info(filename)$size))
}

new.function()

1
Це нічого не додає до відповіді, наданої @Tommy . Надання шляху у функціональному середовищі є особливо поганим рішенням.
Конрад
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.