10

继上周我的查询在 R 不匹配引号中读取格式错误的 csv 之后,这些相同的 CSV 文件还具有嵌入的控制字符,例如十进制 26 或 0x1A的 ASCII替换字符。不幸的是readLines(),似乎截断了这个字符的行,所以我很难匹配引号 - 除了丢失这些行中的后面字段!

我试过了,readBin()但我无法让它读取这个文件。恐怕我无法将其清晰地读入 R 来给您举个例子,而且我在 R 中创建这些内容时遇到了困难。很抱歉不能用一个干净的例子来演示。想法?

更新

现在我很困惑 - 当我使用代码时

 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() 来自 a 时的反应不同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"

即,如果我以二进制文件的形式读入文件并在之后转换为 character(),它似乎可以工作......这对于大型 CSV 文件来说将是乏味的......

R中是否存在错误将Control-Z错误检测为Windows上的文件结尾?

4

2 回答 2

9

我想我已经找到了一个解决方案——因为在 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
}
于 2013-04-08T10:18:56.240 回答
3

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

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

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

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

library(readr)
read_csv2("h3.txt")
于 2015-05-19T19:25:52.470 回答