【问题标题】:How to import CSV into Sqlite in R where one of the variables has a comma (,) within quotes?如何将CSV导入R中的Sqlite,其中一个变量在引号内有逗号(,)?
【发布时间】:2013-06-08 01:53:39
【问题描述】:

这让我发疯了。

我有一个 csv 文件“hello.csv”

a,b
"drivingme,mad",1

我只是想从 R 中将它转换为 sqlite 数据库(我需要这样做,因为实际文件实际上是 10G,它不适合 data.frame,所以我将使用 Sqlite 作为中间数据存储)

dbWriteTable(conn= dbConnect(SQLite(), 
            dbname="c:/temp/data.sqlite3", 
             name="data", 
             value="c:/temp/hello.csv",row.names=FALSE, header=TRUE)

以上代码因错误而失败

Error in try({ : 
  RS-DBI driver: (RS_sqlite_import: c:/temp/hello.csv line 2 expected 2 columns of data but found 3)
In addition: Warning message:
In read.table(fn, sep = sep, header = header, skip = skip, nrows = nrows,  :
  incomplete final line found by readTableHeader on 'c:/temp/hello.csv'

如何告诉它在引号“”中处理逗号(,)被视为字符串而不是分隔符!

我尝试添加参数

quote="\""

但它没有用。帮助!! read.csv 工作只是文件它会在读取大文件时失败。

【问题讨论】:

  • 这是一个known limitation。如果您控制文件的生成方式,一个快速的解决方法是更改​​分隔符,例如 |\t,前提是此字符不会出现在文件的其他任何位置。

标签: r sqlite csv


【解决方案1】:

更新

现在更好的是使用 readr 的分块函数,例如

#setting up sqlite
con_data = dbConnect(SQLite(), dbname="yoursqlitefile")

readr::read_delim_chunked(file, function(chunk) {
  dbWriteTable(con_data, chunk, name="data", append=TRUE )) #write to sqlite 
})

原来比较麻烦的方式

一种方法是从文件中读取,因为 read.csv 可以工作,但它无法将整个数据加载到内存中。

    n = 100000 # experiment with this number
    f = file(csv) 
    con = open(f) # open a connection to the file
    data <-read.csv(f,nrows=n,header=TRUE)
    var.names = names(data)    
 
    #setting up sqlite
    con_data = dbConnect(SQLite(), dbname="yoursqlitefile")
  
    while(nrow(data) == n) { # if not reached the end of line
      dbWriteTable(con_data, data, name="data",append=TRUE )) #write to sqlite 
      data <-read.csv(f,nrows=n,header=FALSE))
      names(data) <- var.names      
    } 
    close(f)
    if (nrow(data) != 0 ) {      
      dbWriteTable(con_data, data, name="data",append=TRUE ))

【讨论】:

  • 我和 OP 有同样的问题,这个答案对我有用。但是,即使我看到它有效,我也无法弄清楚代码每次迭代如何增加 100000 行。你能解释一下吗?
  • 每次出现此行read.csv(f,nrows=n,header=FALSE),都会从文件f 中读取另一行n。通过打开到文件的连接,“读取到哪一行”被保留,所以它只是继续读取。
【解决方案2】:

改进建议的答案:

data_full_path <- paste0(data_folder, data_file)
con_data <- dbConnect(SQLite(),
  dbname=":memory:") # you can also store in a .sqlite file if you prefer

readr::read_delim_chunked(file =  data_full_path,
                          callback =function(chunk,
                                             dummyVar # https://stackoverflow.com/a/42826461/9071968
                                             ) {
                            dbWriteTable(con_data, chunk, name="data", append=TRUE ) #write to sqlite 
                            },
  delim = ";",
  quote = "\""
)

(另一个,当前使用readr的答案不起作用:括号不平衡,块函数需要两个参数,请参阅https://stackoverflow.com/a/42826461/9071968

【讨论】:

    【解决方案3】:

    你制作一个解析器来解析它。

    string = yourline[i];
    if (string.equals(",")) string = "%40";
    yourline[i] = string;
    

    或类似的东西。你也可以使用:

    string.split(",");
    

    并以这种方式重建您的字符串。我就是这样做的。

    请记住,当您想要取回值时,您必须“解解析”它。 SQL 中的逗号表示列,所以它真的会搞砸,更不用说 JSONArrays 或 JSONObjects。

    另外请记住,这对于 10GB 的数据来说可能非常昂贵,因此您可能希望在输入可​​能到达 CSV 之前先解析输入。..

    【讨论】:

      猜你喜欢
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多