2015-01-25 16 views
20

Programatik olarak birçok veri kümesi alıyorum, bunların birçoğunda sayılarla başlayan ve bunlarda eksi işaretler gibi özel karakterler olan aptal isimler var. Veri kümelerinin hiçbiri özellikle büyük olmadığından ve veri türleri hakkında en iyi tahminde bulunma avantajını istedim, bu tabloları SQLite'ye dökmek için dplyr kullanıyorum.Dplyr ile köşeli parantezli tablo adları

Korkunç tablo adlarından kurtulmak için köşeli ayraç kullanıyorum, ancak bu işe yaramıyor.

data(iris) 
foo.db <- src_sqlite("foo.sqlite3", create = TRUE) 
copy_to(foo.db, df=iris, name="[14m3-n4m3]") 

Bu hata iletisine neden olur: Örneğin: Ben mantıklı bir isim seçerseniz

Error in sqliteSendQuery(conn, statement, bind.data) : error in statement: no such table: 14m3-n4m3

Bu çalışır. Ancak, çeşitli nedenlerle, hantal isimleri tutmak istiyorum. Ayrıca sqlite doğrudan böyle bir kötü adlı tablo oluşturmak mümkün duyuyorum:

sqlite> create table [14m3-n4m3](foo,bar,baz); 
sqlite> .tables 
14m3-n4m3 

çok derinden şeylerin içine çatlama olmadan, bu ben çözemiyorum bir şekilde köşeli parantez işleyen dplyr benziyor. Şüphelerim bu bir hata, ama bir şey kaçırmadığımdan emin olmak için ilk önce burada kontrol etmek istedim.

DÜZENLEME: Janky ismini doğrudan dplyr'ye ilettiğim durumdan bahsetmeyi unuttum. Bu hatalar aşağıdaki gibidir:

library(dplyr) 

data(iris) 
foo.db <- src_sqlite("foo.sqlite3", create = TRUE) 
copy_to(foo.db, df=iris, name="14M3-N4M3") 

Error in sqliteSendQuery(conn, statement, bind.data) : 
    error in statement: unrecognized token: "14M3" 
+4

Bu sadece bir tahmindir, ancak R'nin adlandırma kuralları nedeniyle olabilir. Bulduğum olası bir çözüm, 'name = gsub (" [.] "," ", Make.names (" [14m3-n4m3] "))' işlevini kullanmaktır. Bunu yaparsanız, orijinal isimlerinizi yine de copy_to() 'ye aktarabilirsiniz, ancak verilerde biraz farklı olabilirler. Bunun yardımcı olup olmadığından emin değilim ama benim iki sentim.Çok güzel bir soru. –

+1

Bu, uygulama yolundan başladığımdan daha iyi bir çözümdür. Yavaşça kendimi iyi isimler + diğer güçlükler> kötü isimler fikrine konuşuyorum. – Peter

+0

@RichardScriven ile aynı fikirdeyim - mevcut araçları kullanarak isimleri değiştirmek için daha iyi bir şey yapmaya çalışın! –

cevap

3

Bu dplyr'deki bir hatadır. Mevcut github ustasında hala var. @hadley'in belirttiği gibi, bu sorunu önlemek için dplyr'deki tablo adları gibi şeylerden kaçmayı denedi. Şu anki problem, iki fonksiyonda kaçma eksikliğinden kaynaklanıyor. Tablo oluşturma, tablo ismini unscaped sağlandığında iyi çalışır (ve dplyr::db_create_table ile yapılır). Ancak, tabloya veri ekleme, tek tablo adlarını desteklemeyen DBI::dbWriteTable kullanılarak yapılır. Tablo isminin bu işleve bağlı olması durumunda, tablo listesinden (raporladığınız ilk hata) bulamaz. Sunulan sağlanırsa, ekleme yapmak için SQL synatactically geçerli değil.

İkinci sorun, tablonun güncellendiği zaman gelir. Alan adlarını almak için kod, bu kez aslında dplyr,yerine paste0 kullandığı için tablo adından kaçmak için başarısız olur.

Her iki hataları da a fork of dplyr adresinde düzelttim. Ayrıca @hadley için bir çekme isteği koydum ve https://github.com/hadley/dplyr/issues/926 numaralı konuda bir not yazdım. Bu arada, eğer isterseniz, devtools::install_github("NikNakk/dplyr", ref = "sqlite-escape")'u kullanabilir ve sabitlendikten sonra ana versiyona geri dönebilirsiniz.

SQL'de tablo adlarından (ve diğer tanımlayıcılardan) kaçmak için doğru SQL-99 yolu çift tırnak işaretiyle (bkz. SQL standard to escape column names?). MS Access, köşeli parantezleri kullanırken, MySQL varsayılan olarak backtick'lere gider. dplyr standart başına çift tırnak kullanır.

Son olarak, @RichardScriven'den gelen teklif evrensel olarak çalışmaz. Örneğin, select, R'de tam olarak geçerli bir addır, ancak SQL'de sözdizimsel olarak geçerli bir tablo adı değildir. Diğer ayrılmış kelimeler için de aynısı geçerli olacaktır.

+0

Sorunun yanıtlanması için uzun zamandır devam eden bir hata için bir PR verilmesi - bravo! – Peter

+0

Sabit sürümümü indirirken çok hızlı olsaydınız, ekledikten sonra kaynakları temizlemek için fazladan bir kod satırına ekleyen başka bir işlem yaptım. Bunun ne kadar kritik olduğundan emin değilsiniz, ancak orijinal 'DBI :: dbWriteTable' içinde yapılması mantıklı görünmektedir. –

+2

@hadley ile görüştükten sonra, düzeltmem, yukarıda açıklanan ikinci sorunu gideren ("paste0" nin build_sql "ile değiştirilmesi) artık çok daha basit bir tek liner. DBI :: dbWriteTable'da gerekli değişiklikler [github sürümünde [RSQLite] 'de yapılmıştır (https://github.com/rstats-db/RSQLite). DBI] (https://github.com/rstats-db/DBI). –