【问题标题】:read.csv lines with no quotes in RR中没有引号的read.csv行
【发布时间】:2013-09-30 21:18:03
【问题描述】:

我正在尝试从 R 读取一个巨大的 csv 文件,但我遇到了麻烦,因为假定为字符串格式的列的元素没有用引号分隔,并且每次都在那里创建一个新行是一条新线。我的数据由 ~ 分隔。

例如,我的数据看起来类似于:

a ~ b ~ c ~ d ~ e
1 ~ name1 ~ This is a paragraph. 

This is a second paragraph.

~ num1 ~ num2 ~

2 ~ name2 ~ This is an new set of paragraph.

~ num1 ~ num2 ~

我希望得到这样的东西:

一个 |乙 | c | d |电子| ____________________________________________________________________________________ 1 |名称1 |这是一个段落。这是第二段。 |数字1 |数字2 | 2 |名称2 |这是一套新的段落。 |数字1 |数字2 |

但我最终得到了像这样丑陋的东西:

一个 |乙 | c | d |电子| __________________________________________________________________________________ 1 |名称1 |这是一个段落。 | | | 这是第二段| | | | | |数字1 | num2 2 |名称2 |这是一套新的段落。 |数字1 |数字2 |

我试图在 read.csv 中设置 allowEscapes = TRUE 但这并没有奏效。我的输入目前如下所示:

read.csv(filename, header = T, sep = '~', stringAsFactors = F, fileEncoding = "latin1", quote = "", strip.white = TRUE)

我的下一个想法是在每个~之后插入一个引号,但我希望看看是否有更好的方法。

任何帮助将不胜感激。

【问题讨论】:

  • 欢迎来到 SO。请提供样本数据
  • 每一行都以~ 结尾,对吗?
  • @Metrics:我无法真正提供示例数据,因为 1)它又大又乱,2)我是通过主管的数据库获取的,无法真正复制和粘贴数据。但是这个例子应该接近数据
  • @zero323:是的,每一行都以~结尾

标签: r csv read.csv


【解决方案1】:

例如这样的:

ll = readLines(textConnection('a ~ b ~ c ~ d ~ e
1 ~ name1 ~ This is a paragraph. 
This is a second paragraph.
~ num1 ~ num2 ~
2 ~ name2 ~ This is an new set of paragraph.
~ num1 ~ num2 ~'))
## each line begin with a numeric followed by a space
## I use this pattern to sperate lines
llines <- split(ll[-1],cumsum(grepl('^[0-9] ',ll[-1])))
## add the header to the splitted and concatenated lines 
read.table(text=unlist(c(ll[1],lapply(llines,paste,collapse=''))),
           sep='~',header=TRUE)


         a                                                 b      c      d  e
1   name1   This is a paragraph. This is a second paragraph.  num1   num2  NA
2   name2                   This is an new set of paragraph.  num1   num2  NA

【讨论】:

  • 谢谢,我明天试试这个方法,告诉你它是如何工作的
  • “当我运行我必须解析的文档的一部分时”我收到以下错误:比列名更多的列
【解决方案2】:

这是 R 中的一种方法,它依赖于 (1) ~ 是真正的分隔符,不会出现在您的任何段落中,以及 (2) ~ 出现在每条记录的末尾。

但首先,一些示例数据(以其他人也可以重现您的问题的方式)。

cat("a ~ b ~ c ~ d ~ e",
    "1 ~ name1 ~ This is a paragraph.",
    "",
    "This is a second paragraph.",
    "",
    "~ num1 ~ num2 ~",
    "",
    "2 ~ name2 ~ This is an new set of paragraph.",
    "",
    "~ num1 ~ num2 ~", sep = "\n", file = "test.txt")

我们将从readLines 开始获取数据。我们还将在标题行的末尾添加~

x <- readLines("test.txt")
x[1] <- paste(x[1], "~") ## Add a ~ at the end of the first line

现在,我们将paste 全部变成一个漂亮的长字符串。

y <- paste(x, collapse = " ")

使用scan 再次快速“读取”数据,但我们将使用text 参数并引用我们刚刚创建的“y”对象,而不是使用file 参数。由于最后一行以~ 结尾,因此末尾会有一个额外的"",我们将在继续之前将其删除。

z <- scan(text = y, what = character(), sep = "~", strip.white = TRUE)
# Read 16 items
z <- z[-length(z)]

由于我们现在有一个字符向量,我们可以轻松地将其转换为matrix,然后再转换为data.frame。我们知道 colnames 是前 5 个值,因此我们将在创建 matrix 时删除它们,并将它们重新插入为 data.frame 的名称。

df <- setNames(data.frame(
  matrix(z[6:length(z)], ncol = 5, byrow = TRUE)), z[1:5])
df
#   a     b                                                 c    d    e
# 1 1 name1 This is a paragraph.  This is a second paragraph. num1 num2
# 2 2 name2                  This is an new set of paragraph. num1 num2

【讨论】:

  • 哇。 +1。这太棒了。 :-0
【解决方案3】:

当我看到这是一个文本处理问题时,我认为 Python 会容易得多。如果您不熟悉它或无法访问它,我们深表歉意:

import csv

all_rows = []
with open('tilded_csv.txt') as in_file:
    header_line = next(in_file)
    header = header_line.strip().split('~')
    current_record = []
    for line in in_file:
        # Assume that a number at the start of a line
        # signals a new record
        if line[0].isdigit():
            new_record = line.strip()
            if current_record:
                all_rows.append(current_record.split('~'))
            current_record = line.strip()
        else:
            current_record += line.strip()
# Add the last record
all_rows.append(current_record.split('~'))

with open('standard_csv.csv', 'w') as out_file:
    out_csv = csv.writer(out_file, dialect='excel')
    out_csv.writerow(header)
    for row in all_rows:
        out_csv.writerow(row)

【讨论】:

  • 实际上我的首选语言是 python,但是我已经导入了其他需要使用 R 导出到数据库 (postgresql) 的文件,所以我认为我应该坚持使用标准语言来完成这项任务。最坏的情况是使用 python。不过谢谢你的提示。
猜你喜欢
  • 2020-05-14
  • 1970-01-01
  • 2015-01-05
  • 2012-07-04
  • 2020-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多