【问题标题】:How to read a CSV file into R which uses two types of separators in the file?如何将 CSV 文件读入在文件中使用两种分隔符的 R 中?
【发布时间】:2021-10-29 04:24:01
【问题描述】:

我正在尝试将 CSV 文件读入 R,它使用两个不同的分隔符:“,”和“;”。以下是 CSV 格式的简短示例:

"car_brand; car_model","total"
"Toyota; 9289","29781"
"Seat; 20981","1610"
"Volkswagen; 11140","904"
"Suzuki; 11640","658"
"Renault; 13075","647"
"Ford; 15855","553"

CSV 文件应包含 3 列,car_brandcar_modeltotal。但是,car_brandcar_model 用“;”分隔而不是“,”。非常感谢任何有关如何导入此类文件的指导。

【问题讨论】:

标签: r csv


【解决方案1】:

一种选择是使用freadgsub 的组合:

library(data.table)
fread(gsub(";", "", '"car_brand; car_model","total"
"Toyota; 9289","29781"
"Seat; 20981","1610"
"Volkswagen; 11140","904"
"Suzuki; 11640","658"
"Renault; 13075","647"
"Ford; 15855","553"
'))
   car_brand car_model total
1:         Toyota 9289 29781
2:          Seat 20981  1610
3:    Volkswagen 11140   904
4:        Suzuki 11640   658
5:       Renault 13075   647
6:          Ford 15855   553

【讨论】:

  • (坦率地说,这也适用于read.csv,而不仅仅是fread。)
  • @r2evans 是的。我基本上习惯于对所有内容使用fread,并且从不使用base-r版本,因为它快得多,并且在处理不同分隔符等方面似乎也更智能. AFAIK 没有任何理由不使用fread
  • fread 不处理转义的双引号 github.com/Rdatatable/data.table/issues/5088。比较 read.csv(text='col,col2\n"hi ""my friend""",2\n')fread(text='col,col2\n"hi ""my friend""",2\n')
  • (虽然大多数时候我在 CSV 文件中看不到双双引号,但 RFC-4180(第 2 节第 7 节)清楚地说明了嵌入的 dquote 与另一个 dquote 的转义。 )
  • 啊,我不知道。幸运的是,我是一个严格的数字人,从来没有遭受过有人向我发送嵌入双引号的数据:)
【解决方案2】:

一个tidyverse解决方案;

library(tidyverse)

read.csv('file.csv',header = T) %>%
separate(col='car_brand..car_model',into = c('car_brand','car_model'),sep = ';') %>%
 mutate(car_model=as.numeric(car_model)) 

输出;

car_brand  car_model total
  <chr>          <dbl> <int>
1 Toyota          9289 29781
2 Seat           20981  1610
3 Volkswagen     11140   904
4 Suzuki         11640   658
5 Renault        13075   647
6 Ford           15855   553

【讨论】:

    【解决方案3】:

    双击:

    x1 <- read.csv("quux.csv", check.names = FALSE)
    x2 <- read.csv2(text = x1[[1]], header = FALSE)
    names(x2) <- unlist(read.csv2(text = names(x1)[1], header = FALSE))
    cbind(x2, x1[,-1,drop=FALSE])
    #    car_brand  car_model total
    # 1     Toyota       9289 29781
    # 2       Seat      20981  1610
    # 3 Volkswagen      11140   904
    # 4     Suzuki      11640   658
    # 5    Renault      13075   647
    # 6       Ford      15855   553
    

    需要使用check.names=FALSE,否则names(x1)[1] 看起来像"car_brand..car_model"。虽然可以这样解析,但我觉得还是解析原文比较好。

    【讨论】:

      【解决方案4】:

      如果您自己编写 csvImporter,您只需在循环中动态更改分隔符(取决于索引)。

      【讨论】:

      • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多