4

これを理解するのに少し時間がかかりました。だから、私は自分の質問に答えています

いくつかの.csvがあり、それを高速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)
  

--FAQ.13ソリューションも機能しませんsqldf

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

繰り返しますが、Rは文句を言います

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

実際、フィルターは二重引用符のみを削除します。

では、どのように進めますか?

4

2 に答える 2

3

Perl と正規表現が助けになります。SO を掘り下げて、ここで正規表現をいじると、正しいものを思いつくのはそれほど難しくありません。

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

これは に一致"...,..."します。ここで、ドットは二重引用符とコンマ以外のものであり、コンマをアンダースコアに置き換えます。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 cosmesis…

EDIT : 上記の正規表現は、フィールド内の最初のカンマのみを置き換えます。すべての発生を置き換えるには、これを使用します

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

何が違うの?

  1. 区切り文字/{};に置き換えました。
  2. 最後のオプション e は、置換フィールドを perl コードとして解釈するようにパーサーに指示します。
  3. 置換は単純な正規表現置換であり、一致した部分文字列内のすべての " ," を " " に置き換えます。_$&

例:

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
于 2011-11-10T21:31:00.203 に答える
0

Windows の場合、sqldf にはtrcomma2dot.vbsが付属するようになりました。これはデフォルトで read.csv2.sql でこれを行います。非常に大きなデータ(> 100万行)では遅いことがわかりましたが

非Windowsベースのシステムの「tr」について言及されていますが、試すことができませんでした。

于 2015-06-19T19:55:23.077 に答える