1

这让我发疯。

我有一个 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 工作只是文件,读取大文件时会失败。

4

3 回答 3

3

更新

现在更好的是使用readr's 分块功能,例如

#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 ))
于 2013-06-19T07:20:33.663 回答
0

改进建议的答案:

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

于 2021-04-15T14:04:49.247 回答
-1

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

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

或类似的东西。您还可以使用:

string.split(",");

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

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

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

于 2013-06-12T03:35:28.403 回答