【问题标题】:How does read.csv work? What if I have a data set with different columns?read.csv 是如何工作的?如果我有一个包含不同列的数据集怎么办?
【发布时间】:2020-05-12 21:19:57
【问题描述】:

我有一个数据集。当我使用 read.csv 导入数据时,我收到警告说某些观察应该有 4 列但实际上少于 4 列。

当我检查数据时,我发现一些观察被分成两行,如下所示:(#3观察)

Number, name, value_1, value_2
1,      'A',  2,       3
2,      'B',  4,       5
3,      'C',  7
8
4,      'D',  9,       10
5,      'E',  11,      12 

那么,我想知道我该如何解决这个问题?

我的数据集很大。因此,手动纠正错误将非常耗时。

【问题讨论】:

  • 如果数据格式不正确,您将很难将其读入read.csv。是什么产生了这样一个无效的 csv 文件?尝试解决该问题比在 R 中事后清理它要好。否则您基本上必须将输入视为字符串,将其转换为适当的 CSV 文件,然后使用 read.csv 读取它.
  • 读取带有嵌入换行符的 CSV 文件(看起来是这样)在多个层面上都是有问题的。首先,虽然可以推断出第 1-3 列中嵌入的换行符(通过列数不足),但第 4 列中的换行符显然不会被拆分,直到查看下一行以查看它包含零字段- 分隔符(逗号)。我不知道有任何“标准” CSV 解析器可以为您推断出这一点,虽然不是很困难,但几乎可以肯定它会很慢。
  • 好像是“8”前换行错误。使用文本编辑器并修复它。
  • 如果你有任何控制权,我会回到数据源并在那里修复它。如果它只有一行并且您不介意手动干预,请按照@tpetzoldt 的建议进行操作并编辑文件并修复该行(以及其他类似的行)。
  • 同意 MrFlick 和其他人的观点。如果数据集易于管理,您可能希望将其导入 Excel,而不是使用简单的文本编辑器。因为这样您就可以过滤空白以隔离问题行并轻松将放错位置的值拖到它们所属的位置。

标签: r tidyverse read.csv


【解决方案1】:

尝试使用 read.csv 函数的 fill 参数来加载不完整的行,其中 NA 用于缺失值。这里使用 read.table 函数演示了 fill 参数:

df <- read.table(text="Number, name, value_1, value_2
                      1,      'A',  2,       3
                      2,      'B',  4,       5
                      3,      'C',  7
                      8
                      4,      'D',  9,       10
                      5,      'E',  11,      12", 
                   sep = ",", fill = T, header = T, stringsAsFactors = F)

df

# Number    name value_1 value_2
# 1      1       A       2       3
# 2      2       B       4       5
# 3      3       C       7      NA
# 4      8              NA      NA
# 5      4       D       9      10
# 6      5       E      11      12

注意这里第四条记录“name”的值没有被导入为NA,而是一个空字符串。

您可以将相同的填充参数传递给 read.csv:

df <- read.csv("myfile.csv", header = T, sep = ",", fill = T, stringsAsFactors = F)

如果您仍然无法使用 read.csv 函数使用 fill 参数导入文件,那么我建议使用 read.table 和 sep="\n" (换行符)逐行导入数据,然后清理并从 R 中的结果字符串解析数据,而不是手动编辑文件。这种清理将如何进行很大程度上取决于文件中的异常情况,但对于提供的示例数据,这样的事情适用,但假设行上的所有缺失值在可用数据的右侧同样缺失:

require(stringr)

lines <- read.table(text="Number, name, value_1, value_2\n
                      1,      'A',  2,       3\n
                      2,      'B',  4,       5\n
                      3,      'C',  7\n
                      8\n
                      4,      'D',  9,       10\n
                      5,      'E',  11,      12\n", 
                 sep = "\n", fill = T, header = T, stringsAsFactors = F)

record_list <- apply(lines, 1, FUN= function(x){str_squish(str_split(x, ",", simplify = T))})

# Assuming all missing values are to the right of present values on a line
na_filled <- sapply(record_list, FUN = function(x){x <- c(x, rep.int(as.character(NA), 4 - length(x)))})


df <- data.frame(t(na_filled), stringsAsFactors = F)

names(df) <- c("Number", "name", "value_1", "value_2")

df

# Number name value_1 value_2
# 1      1    A       2       3
# 2      2    B       4       5
# 3      3    C       7    <NA>
# 4      8 <NA>    <NA>    <NA>
# 5      4    D       9      10
# 6      5    E      11      12

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 2020-06-10
    • 2023-01-29
    相关资源
    最近更新 更多