【问题标题】:How to ignore delimiters inside quoted strings when importing a csv file with RSQLite?使用 RSQLite 导入 csv 文件时如何忽略带引号的字符串中的分隔符?
【发布时间】:2019-08-26 22:02:33
【问题描述】:

我想导入一个与以下示例结构类似的 csv 文件:

var1;var2;var3
"a";1;"Some text"
"b";0;"More text"
"c;0;"Delimiter in ; middle of the text"

传统的解析器,例如 data.table::fread 使用的解析器默认处理这个问题。我想使用RSQLite::dbWriteTable 将此数据导入到 SQLite 数据库。

con <- DBI::dbConnect(RSQLite::SQLite(), dbname = "mydb.sqlite")
dbWriteTable(conn = con, name = "my_table", value = "data_file.csv")

dbWriteTable 中没有提供引号的选项,因此当找到有问题的行时,该函数会引发错误。我怎样才能导入这些数据?我唯一的限制是在导入 SQLite 之前我没有足够的内存来解析 R 的数据。

【问题讨论】:

    标签: r sqlite r-dbi dbplyr


    【解决方案1】:

    安装在 Windows 和 Linux 平台上可用的 csvfix 实用程序,然后尝试此测试代码。它在 Windows 上对我有用。您可能需要针对其他平台稍微调整它,特别是您可能不需要的 shell 行和 eol= 参数,或者您可能需要不同的值。我们使用 csvfix 去除引号并将不在字段中的分号替换为 @。然后我们在读入的时候使用@分隔符。

    首先我们创建测试数据。

    # if (file.exists("mydb")) file.remove("mydb")
    # if (file.exists("data_file2.csv")) file.remove("data_file2.csv")
    
    # write out test file
    cat('var1;var2;var3\n"a";1;"Some text"\n"b";0;"More text"\n"c";0;"Delimiter in ; middle of the text"', file = "data_file.csv")
    
    # create database (can omit if it exists)
    cat(file = "mydb")
    

    csvfix

    现在用 csvfix 处理数据文件

    library(RSQLite)
    
    # preprocess file using csvfix - modify next line as needed depending on platform
    shell("csvfix write_dsv -sep ; -s @ data_file.csv > data_file2.csv")
    file.show("data_file2.csv") # omit this line for real data
    
    # write file to database
    con <- dbConnect(SQLite(), "mydb")
    dbWriteTable(con, "myFile", "data_file2.csv", sep = "@", eol = "\r\n")
    dbGetQuery(con, "select * from myFile") # omit this line for real data
    dbDisconnect(con)
    

    xsv

    另外安装xsv rust 实用程序。这在 Windows 上对我有用。

    library(RSQLite)
    
    shell("xsv fmt -d ; -t @ data_file.csv > data_file2.csv")
    file.show("data_file2.csv") # omit this line for real data
    
    # write file to database
    con <- dbConnect(SQLite(), "mydb")
    dbWriteTable(con, "myFile", "data_file2.csv", sep = "@")
    dbGetQuery(con, "select * from myFile") # omit this line for real data
    dbDisconnect(con)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-25
      • 1970-01-01
      • 2015-07-20
      相关资源
      最近更新 更多