นำเข้าไฟล์ข้อความเป็นสตริงอักขระเดียว


204

คุณจะนำเข้าไฟล์ข้อความธรรมดาเป็นสตริงอักขระตัวเดียวใน R ได้อย่างไร ฉันคิดว่านี่อาจจะเป็นคำตอบที่ง่ายมาก แต่เมื่อฉันลองวันนี้ฉันพบว่าฉันไม่สามารถหาฟังก์ชั่นการทำเช่นนี้ได้

ตัวอย่างเช่นสมมติว่าฉันมีไฟล์foo.txtพร้อมสิ่งที่ฉันต้องการส่งข้อความ

ฉันลองด้วย:

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

แต่นี่กลับเป็นเวกเตอร์ ฉันได้รับมันทำงานค่อนข้างด้วย:

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

แต่นั่นเป็นวิธีแก้ปัญหาที่น่าเกลียดซึ่งอาจไม่แน่นอนเช่นกัน


20
readr::read_fileแก้ปัญหานี้ได้อย่างดีตอนนี้
Zach

คำตอบ:


213

นี่คือความแตกต่างของโซลูชันจาก @JoshuaUlrich ที่ใช้ขนาดที่ถูกต้องแทนที่จะเป็นขนาดฮาร์ดโค้ด:

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

โปรดทราบว่า readChar จัดสรรพื้นที่สำหรับจำนวนไบต์ที่คุณระบุดังนั้นจึงreadChar(fileName, .Machine$integer.max)ใช้งานไม่ได้ ...


18
เป็นมูลค่าชี้ให้เห็นว่ารหัสนี้จะไม่ทำงานสำหรับไฟล์บีบอัด ในกรณีนั้นจำนวนไบต์ที่ส่งกลับโดย file.info (ชื่อไฟล์) $ ขนาดจะไม่ตรงกับเนื้อหาจริงที่จะอ่านในหน่วยความจำซึ่งเราคาดว่าจะมีขนาดใหญ่กว่า
asieira

146

ในกรณีที่ทุกคนยังคงดูคำถามนี้ 3 ปีต่อมาแพคเกจ readr ของ Hadley Wickham มี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
Michael Lloyd Lee mlk

7
@mlk readrจะได้รับการอพยพไป ฉันได้อัปเดตคำตอบแล้ว - ฉันหวังว่าชารอนจะไม่สนใจ
Nick Kennedy

1
ดีมาก! ยังขยายขนาดไฟล์. gz ได้อย่างรวดเร็ว
Andre Holzner

ฉันได้รับcould not find function "pase"ในรหัสนี้
Sashko Lykhenko

47

ฉันจะใช้ต่อไปนี้ มันควรจะใช้ได้ดีและดูเหมือนจะไม่น่าเกลียดอย่างน้อยสำหรับฉัน:

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

15
ฉันคาดว่าcollapse="\n"จะทำซ้ำความจริงที่ว่าสิ่งเหล่านี้เป็นบรรทัดแยกต่างหากในไฟล์ต้นฉบับ ด้วยการเปลี่ยนแปลงนี้โซลูชันนี้จะทำงานสำหรับไฟล์ที่บีบอัดและไม่บีบอัดได้ดีเท่ากัน
asieira

ดูเหมือนจะใช้งานไม่ได้ ถ้าฉันเขียนไลน์ (singleString) ฉันจะได้รับไฟล์ที่เสียหาย ...
bumpkin

สิ่งนี้จะไม่ทำงานหากบรรทัดสุดท้ายไม่มีอักขระสิ้นสุดบรรทัด ในกรณีนั้นบรรทัดสุดท้ายจะไม่รวมอยู่ในสตริง (หรือมิฉะนั้นไฟล์จะถูกตัดทอนที่ตัวแบ่งบรรทัดสุดท้าย)
gvrocha

สิ่งนี้จะทำงานได้ดีสำหรับการอ่านไฟล์ข้อความเช่นเดียวกับเควสต์ของ OPON: การเชื่อมต่อไฟล์ข้อความเป็นblocking=TRUEค่าเริ่มต้นดังนั้นreadLines()จะส่งคืนไฟล์เต็มพร้อมคำเตือนเกี่ยวกับอักขระ EOL ที่หายไป อย่างไรก็ตามความคิดเห็นของ @ gvrocha นั้นมีค่าควรระวัง: เข้าใจประเภทการเชื่อมต่อของคุณ! ? readLines help saysIf 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

แพ็คเกจ readr มีฟังก์ชั่นที่จะทำทุกอย่างให้คุณ

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

น่าเสียดายที่โซลูชันของ Sharon ไม่สามารถใช้ได้อีกต่อไป ฉันได้เพิ่มวิธีการแก้ปัญหาของ Josh O'Brien ด้วยการดัดแปลง asieira ลงในไฟล์. profile ของฉัน:

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 และ paste)

ฉันได้เพิ่มช่องว่างระหว่างแต่ละบรรทัดด้วย:

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 การให้เส้นทางภายในสภาพแวดล้อมของฟังก์ชั่นเป็นวิธีการแก้ปัญหาที่แย่
Konrad
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.