【问题标题】:Possible to change the record delimiter in R?可以更改R中的记录分隔符吗?
【发布时间】:2013-04-20 02:25:22
【问题描述】:

从文本文件中读取数据(即 read.table)时,是否可以操作记录/观察/行分隔符?使用 sep="" 调整字段分隔符很简单,但我还没有找到一种方法来更改行尾字符的记录分隔符。

我正在尝试读取以管道分隔的文本文件,其中许多条目是包含回车符的长字符串。 R 将这些 CR 视为行尾,这会错误地开始新行并搞砸记录数和字段顺序。

我想使用不同的分隔符而不是 CR。事实证明,每一行都以相同的字符串开头,所以如果我可以使用 \nString 之类的东西来识别 true 行尾,那么表格将正确导入。以下是其中一个文本文件可能是什么样子的简化示例。

V1,V2,V3,V4
String,A,5,some text
String,B,2,more text and
more text
String,B,7,some different text
String,A,,

应该读入 R 为

V1      V2       V3      V4
String  A        5       some text
String  B        2       more text and more text
String  B        7       some different text
String  A        N/A     N/A

我可以在文本编辑器中打开文件并在读入之前使用查找/替换来清理它们,但是 R 中的系统解决方案会很棒。感谢您的帮助。

【问题讨论】:

  • 但是你还会改变记录分隔符吗?它不一致,需要以某种方式进行清洁。如果这就是您所拥有的,那么您可以将其作为未格式化的原始文本读取,搜索不以“String”开头的行并将它们附加到前一行并发送到 read.table 进行格式化。但这真的是所有需要解决的问题吗?
  • 是的,这可能是看待它的正确方式。无论如何,一个更好的方法。这基本上就是GG的解决方案所做的,对吧?

标签: regex r delimiter


【解决方案1】:

我们可以将它们读入并在之后折叠它们。 g 将具有值 0 用于标题,1 用于下一行(以及后续行,如果有的话,将与它一起使用)等等。 tapply 根据gL2 折叠行,最后我们重新读取行:

Lines <- "V1,V2,V3,V4
String,A,5,some text
String,B,2,more text and
more text
String,B,7,some different text
String,A,,"

L <- readLines(textConnection(Lines))

g <- cumsum(grepl("^String", L))
L2 <- tapply(L, g, paste, collapse = " ")

DF <- read.csv(text = L2, as.is = TRUE)
DF$V4[ DF$V4 == "" ] <- NA

这给出了:

> DF
      V1 V2 V3                      V4
1 String  A  5               some text
2 String  B  2 more text and more text
3 String  B  7     some different text
4 String  A NA                    <NA>

【讨论】:

    【解决方案2】:

    如果您使用的是 Linux/Mac,那么您确实应该使用命令行工具,例如sed,而不是。以下是两种略有不同的方法:

    # keep the \n
    read.csv(pipe('sed \'N; s/\\([^,]*\\)\\n\\([^,]*$\\)/"\\1\\n\\2"/\' test.txt'))
    #      V1 V2 V3                       V4
    #1 String  A  5                some text
    #2 String  B  2 more text and\nmore text
    #3 String  B  7      some different text
    #4 String  A NA
    
    # get rid of the \n and replace with a space
    read.csv(pipe('sed \'N; s/\\([^,]*\\)\\n\\([^,]*$\\)/\\1 \\2/\' test.txt'))
    #      V1 V2 V3                      V4
    #1 String  A  5               some text
    #2 String  B  2 more text and more text
    #3 String  B  7     some different text
    #4 String  A NA
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 2018-10-05
      • 1970-01-01
      • 2013-08-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多