【问题标题】:How to read a text file into GNU R with a multiple-byte separator?如何使用多字节分隔符将文本文件读入 GNU R?
【发布时间】:2011-10-25 01:51:08
【问题描述】:

我可以使用 read.csv 或 read.csv2 将数据读入 R。但我遇到的问题是我的分隔符是多字节字符串而不是单个字符。我该如何处理?

【问题讨论】:

  • 你的多字节字符串是什么?
  • 我相信如果你看更通用的 read.table() 和 sep 参数,你可以使用多字节字符串。
  • @mweylandt 我认为read.table()sep 只接受单个字节(scan() 也一样)。
  • @jthetzel,哎呀:对不起。我喜欢你下面的解决方案

标签: r csv


【解决方案1】:

提供示例数据会有所帮助。不过,您或许可以根据自己的需要调整以下内容。

我创建了一个示例数据文件,它只是一个包含以下内容的文本文件:

1sep2sep3
1sep2sep3
1sep2sep3
1sep2sep3
1sep2sep3
1sep2sep3
1sep2sep3

我将其保存为“test.csv”。分隔字符是“sep”字符串。我认为read.csv() 使用scan(),它只接受sep 的单个字符。要绕过它,请考虑以下事项:

dat <- readLines('test.csv')
dat <- gsub("sep", " ", dat)
dat <- textConnection(dat)
dat <- read.table(dat)

readLines() 只是读取行。gsub 将多字符分隔字符串替换为单个 ' ',或任何方便您的数据的字符串。然后textConnection()read.data() 方便地读回所有内容。对于较小的数据集,这应该没问题。如果您有非常大的数据,请考虑使用 AWK 之类的东西进行预处理以替换多字符分隔字符串。以上来自http://tolstoy.newcastle.edu.au/R/e4/help/08/04/9296.html

更新 关于您的评论,如果您的数据中有空格,请使用不同的替换分隔符。考虑将test.csv 更改为:

1sep2 2sep3
1sep2 2sep3
1sep2 2sep3
1sep2 2sep3
1sep2 2sep3
1sep2 2sep3
1sep2 2sep3 

然后,使用以下函数:

readMulti <- function(x, sep, replace, as.is = T)
{
    dat <- readLines(x)
    dat <- gsub(sep, replace, dat)
    dat <- textConnection(dat)
    dat <- read.table(dat, sep = replace, as.is = as.is)

    return(dat)
}

试试:

readMulti('test.csv', sep = "sep", replace = "\t", as.is = T)

在这里,您将原始分隔符替换为制表符 (\t)。 as.is 被传递给 read.table() 以防止字符串被读入是因素,但这是你的电话。如果您的数据中有更复杂的空白,您可能会发现 read.table() 中的 quote 参数很有帮助,或者使用 AWK、perl 等进行预处理。

与 crippledlambda 的 strsplit() 类似的东西很可能等效于中等大小的数据。如果性能成为问题,请尝试两种方法,看看哪种方法适合您。

【讨论】:

  • read.table 将得到相同的错误消息。jthetzel 的建议听起来不错。实际上,在我用 R 读取原始数据之前,我已经利用 awk 来处理原始数据。但这里的问题是我们如何处理使用 gsub 之后的新分隔字符中的字符(比如说,我们在您的示例代码中的值中有一个 ' ')。
  • @RobinMin 在上面的每个更新中尝试不同的替换分隔符。
【解决方案2】:

在这种情况下,您可以将textConnection(txt) 替换为您的文件名,但实际上您可以围绕strsplit 构建代码或函数。在这里,我假设您有一个标题行,但您当然可以定义一个 header 参数并根据以下函数概括您的数据框的创建:

read.multisep <- function(File,sep) {
    Lines <- readLines(File)
    Matrix <- do.call(rbind,strsplit(Lines, sep, fixed = TRUE))
    DataFrame <- structure(data.frame(Matrix[-1,]), names=Matrix[1,]) ## assuming header is present
    DataFrame[] <- lapply(DataFrame, type.convert)                    ## automatically convert modes
    DataFrame
}

example <- "a#*&b#*&c
            1#*&2#*&3
            4#*&5#*&6"

read.multisep(textConnection(example),sep="#*&")

  a b c
1 1 2 3
2 4 5 6

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 2013-08-13
    • 2013-10-16
    • 1970-01-01
    • 1970-01-01
    • 2014-06-12
    相关资源
    最近更新 更多