2011-11-10 75 views
3

花了我一会儿才弄明白这一点。所以,我是answering my own questionsqldf,csv和包含逗号的字段

你有一些.csv,你想加载它fast,你想使用sqldf包。你平时的代码被一些烦人的领域激怒了。示例:

1001,  Amy,9:43:00, 99.2 
1002,"Ben,Jr",9:43:00, 99.2 
1003,"Ben,Sr",9:44:00, 99.3 

此代码仅适用于* nix系统。

library(sqldf) 
system("touch temp.csv") 
system("echo '1001, Amy,9:43:00, 99.2\n1002,\"Ben,Jr\",9:43:00, 99.2\n1003,\"Ben,Sr\",9:44:00, 99.3' > temp.csv") 

如果尝试

x <- read.csv.sql("temp.csv", header=FALSE) 

R键读抱怨

Error in try({ : 
    RS-DBI driver: (RS_sqlite_import: ./temp.csv line 2 expected 4 columns of data but found 5) 

sqldf - FAQ.13解决方案不起作用或者:

x <- read.csv.sql("temp.csv", filter = "tr -d '\"' ", header=FALSE) 

此外,R合作mplains

Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings, : 
    line 1 did not have 5 elements 

实际上,该过滤器仅删除双引号。

那么,该如何进行呢?

+0

我已经澄清并改进了常见问题解答,并且在这里包含了一个带有链接库的Perl代码的gawk版本。 –

+0

我最初已经把你和其他人混淆了,你必须在我修好这个名字之前看到它。 –

回答

3

Perl和正则表达式来救援。经历了这么挖掘,并用正则表达式here玩弄,这是不是太硬拿出正确的:它匹配"...,...",这里的点是什么,但双引号和逗号

s/(\"[^\",]+),([^\"]+\")/$1_$2/g 

,并与substitues逗号下划线。一个Perl的单行是传递给sqldf右过滤器:

x <- read.csv.sql("temp.csv", 
     filter = "perl -e 's/(\"[^\",]+)_([^\"]+\")/$1_$2/g'", 
     header=FALSE) 

下面是数据帧x

> x 
    V1  V2  V3 V4 
1 1001  Amy 9:43:00 99.2 
2 1002 "Ben_Jr" 9:43:00 99.2 
3 1003 "Ben_Sr" 9:44:00 99.3 

现在,串DYO美容效果......

编辑:上面的正则表达式仅替换了该字段中第一次出现逗号。要替换所有发行货币,请使用此

s{(\"[^\",]+),([^\"]+\")}{$_= $&, s/,/_/g, $_}eg 

有什么不同?

  1. 我用{}替换了分隔符/;
  2. 最后的选项e指示解析器将替换字段解释为Perl代码;
  3. 该replecement是一个简单的正则表达式替换,它替换匹配的子字符串$&内的所有“,”和“_”。

一个例子:

system("touch temp.csv") 
system("echo '1001, Amy,9:43:00, 99.2\n1002,\"Ben,Jr,More,Commas\",9:43:00, 99.2\n1003,\"Ben,Sr\",9:44:00, 99.3' > temp.csv") 

文件temp.csv样子:

1001,     Amy,9:43:00, 99.2 
1002,"Ben,Jr,More,Commas",9:43:00, 99.2 
1003,   "Ben,Sr",9:44:00, 99.3 

,可与

x <- read.csv.sql("temp.csv", 
     filter = "perl -p -e 's{(\"[^\",]+),([^\"]+\")}{$_= $&, s/,/_/g, $_}eg'", 
     header=FALSE) 
> x 
    V1     V2  V3 V4 
1 1001     Amy 9:43:00 99.2 
2 1002 "Ben_Jr_More_Commas" 9:43:00 99.2 
3 1003    "Ben_Sr" 9:44:00 99.3 
+0

在read.csv.sql函数中加入过滤器参数会导致错误:文件错误(file,“rt”):无法打开连接另外:警告消息:在文件(file,“rt”)中:无法打开文件'C:\ Users \ user \ AppData \ Local \ Temp \ Rtmpcbqrz6 \ filee4819344504':没有这样的文件或目录。'我在RStudio中编写cmd'x < - read.csv.sql(“D: /d/myfile.csv“,sql =”Select * from agent where agent ='agnt1455'“,filter =”perl -e's /(\“[^ \”,] +)_([^ \“] + \“)/ $ 1_ $ 2/g'”)' – Akki

0

对于Windows读取,sqldf现在自带trcomma2dot.vbs它不t他默认使用read.csv2.sql。虽然发现它对于非常大的数据很慢(> 100万行)

它提到了非tr系统的“tr”,但我无法尝试。

+0

请注意,'trcomma2dot'将所有逗号转换为点,而不是引号中的逗号。 –

相关问题