在Windows上使用R中的SUB(1a)(Control-Z)字符读取文本文件

继上个星期我的查询中, 读取了R不匹配的引号中的格式不正确的csv ,这些相同的CSV文件也具有embedded的控制字符,例如十进制26或0x1A的ASCII replace字符 。 不幸的是, readLines()似乎在这个字符处截断了行,所以我很难匹配引号 – 除了丢失这些行的后面的字段!

我试图readBin()但我不能读取这个文件。 我害怕我不能干净地把它读入R来给你一个例子,我很难在R中创build它们。对不起,不能用一个干净的例子来演示。 思考?

更新

现在我很困惑 – 当我使用代码

  h3 <- paste('1,34,44.4,"', rawToChar(as.raw(c(as.integer(k1), 26, 65))), '",99') identical(readLines(textConnection(h3)), h3) 

我得到TRUE ,我觉得很惊讶!

更新2

  h3 [1] "1,34,44.4,\" HIJK\032A \",99" > writeLines(h3, 'h3.txt') > h3a <- readLines('h3.txt') Warning message: In readLines("h3.txt") : incomplete final line found on 'h3.txt' > h3a [1] "1,34,44.4,\" HIJK" 

所以readLines()在来自textConnection()时候textConnection()不同的反应,并且它会在SUB字符处自动截断。

如果它有所作为,我会感到惊讶,但我在Windows-64上的2.15.2。

更新3

一些模糊的成功解决这个…

 zb <- file('h3.txt', "rb") tmp <- readBin(zb, raw(), size=1, n=400) # raw is always of size =1 nchar(tmp) # [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 close(zb) tmp # [1] 31 2c 33 34 2c 34 34 2e 34 2c 22 20 48 49 4a 4b 1a 41 20 22 2c 39 39 0d 0a rawToChar(tmp) # [1] "1,34,44.4,\" HIJK\032A \",99\r\n" 

即如果我在文件中读取二进制文件,然后转换为字符(),似乎工作…这将是繁重的大型CSV文件…

在R中错误地检测到一个Control-Z作为文件结尾的错误?

我想我已经想出了一个解决方案 – 因为在Windows上的文件中间读取Control-Z似乎有问题,我们需要以二进制/原始模式读取文件。

 fnam <- 'h3.txt' tmp.bin <- readBin(fnam, raw(), size=1, n=max(2*file.info(dfnam)$size, 100))=1 tmp.char <- rawToChar(tmp.bin) txt <- unlist(strsplit(tmp.char, '\r\n', fixed=TRUE)) txt [1] "1,34,44.4,\" HIJK\032A \",99" 

更新以下更好的答案由Duncan Murdoch发布给R-Devel 参考 。 将其转换为函数我得到:

 sReadLines <- function(fnam) { f <- file(fnam, "rb") res <- readLines(f) close(f) res } 

当我使用包含在文件中间的SUB或CTRL-Z的csv文件的read.csv时,我也遇到了这个问题。

使用readr包解决它(如果您的文件是逗号分隔)

 library(readr) read_csv("h3.txt") 

如果你有一个; 作为分隔符,然后使用:

 library(readr) read_csv2("h3.txt")