2015-01-25 6 views
20

मैं प्रोग्रामेटिक रूप से डेटासेट का एक गुच्छा ला रहा हूं, उनमें से कई मूर्खतापूर्ण नाम हैं जो संख्याओं से शुरू होते हैं और उनमें विशेष माइनस संकेत जैसे विशेष वर्ण होते हैं। चूंकि कोई भी डेटासेट विशेष रूप से बड़ा नहीं होता है, और मैं चाहता हूं कि लाभ आर डेटा प्रकारों के बारे में अपना सर्वश्रेष्ठ अनुमान लगाए, मैं इन तालिकाओं को SQLite में डंप करने के लिए dplyr का उपयोग कर रहा हूं।ब्रैकेट-बच निकले हुए टेबल नाम 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: no such table: 14m3-n4m3

यह काम करता है अगर मैं एक समझदार नाम चुनें। हालांकि, कई कारणों से, मैं वास्तव में बोझिल नाम रखना चाहता हूं। मैं भी SQLite से सीधे इस तरह के एक बुरी तरह से नाम तालिका बनाने के लिए कर रहा हूँ:

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

भी गहरा चीजों में खुर के बिना, इस dplyr तरह लग रहा है किसी तरह से है कि मैं समझ नहीं में वर्ग कोष्ठक से निपटने है। मेरा संदेह यह है कि यह एक बग है, लेकिन मैं यह सुनिश्चित करने के लिए पहले यहां जांचना चाहता था कि मुझे कुछ याद नहीं आया।

संपादित करें: मैं उस मामले का उल्लेख करना भूल गया जहां मैं सिर्फ janky नाम को सीधे dplyr पास करता हूं। निम्नानुसार त्रुटियां:

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

यह सिर्फ एक अनुमान है, लेकिन यह आर के नामकरण सम्मेलनों के कारण हो सकता है। मुझे मिला एक संभावित कामकाज 'name = gsub ("[।]", "", Make.names ("[14m3-n4m3]") का उपयोग करना है। यदि आपने ऐसा किया है तो आप अभी भी अपने मूल नाम 'copy_to() 'में पास कर सकते हैं, हालांकि वे डेटा में थोड़ा अलग होंगे। यकीन नहीं है कि अगर यह मदद करता है लेकिन यह मेरे दो सेंट है।बहुत अच्छा सवाल है। –

+1

यह कार्यान्वित करने की सड़क से शुरू होने से बेहतर कामकाज है। धीरे-धीरे इस विचार में बात कर रहे हैं कि अच्छे नाम + अन्य परेशानी> बुरे नाम। – Peter

+0

मैं @RichardScriven से सहमत हूं - अपने आप को रोल करने की कोशिश करने के बजाय मौजूदा उपकरणों के नामों को संशोधित करने के लिए बेहतर! –

उत्तर

3

यह dplyr में एक बग है। यह अभी भी वर्तमान जिथब मास्टर में है। जैसा कि @ हैडली इंगित करता है, उसने इस मुद्दे को रोकने के लिए टेबल नामों जैसी चीजों से बचने की कोशिश की है। वर्तमान कार्य जो आप हो रहे हैं, दो कार्यों में भागने की कमी से उत्पन्न होता है। तालिका निर्माण अनदेखा (और dplyr::db_create_table के साथ किया जाता है) प्रदान करते समय तालिका निर्माण ठीक काम करता है। हालांकि, तालिका में डेटा सम्मिलन DBI::dbWriteTable का उपयोग करके किया जाता है जो विषम तालिका नामों का समर्थन नहीं करता है। यदि इस फ़ंक्शन पर तालिका का नाम प्रदान किया गया है, तो यह तालिकाओं की सूची (आपके द्वारा रिपोर्ट की गई पहली त्रुटि) में इसे ढूंढने में विफल रहता है। यदि यह उपलब्ध कराया गया है, तो एसक्यूएल सम्मिलन करने के लिए synatactically मान्य नहीं है।

दूसरा मुद्दा तब आता है जब तालिका अद्यतन होती है। फ़ील्ड नाम प्राप्त करने के लिए कोड, इस बार वास्तव में dplyr में, फिर से तालिका नाम से बचने में विफल रहता है क्योंकि यह build_sql के बजाय paste0 का उपयोग करता है।

मैंने a fork of dplyr पर दोनों त्रुटियों को ठीक किया है। मैंने @ हैडली को पुल अनुरोध भी दिया है और इस मुद्दे पर https://github.com/hadley/dplyr/issues/926 पर एक नोट बनाया है। इस बीच, यदि आप चाहते थे कि आप devtools::install_github("NikNakk/dplyr", ref = "sqlite-escape") का उपयोग कर सकें और फिर इसे ठीक करने के बाद मास्टर संस्करण पर वापस आएं।

संयोग से, SQL में तालिका नाम (और अन्य पहचानकर्ता) से बचने के लिए सही SQL-99 तरीका डबल कोट्स के साथ है (SQL standard to escape column names? देखें)। एमएस एक्सेस स्क्वायर ब्रैकेट का उपयोग करता है, जबकि MySQL बैकटिक्स पर डिफ़ॉल्ट है। dplyr मानक प्रति डबल कोट्स का उपयोग करता है।

अंत में, @ रिचर्डस्क्रीन का प्रस्ताव सार्वभौमिक रूप से काम नहीं करेगा। उदाहरण के लिए, select आर में एक बिल्कुल मान्य नाम है, लेकिन SQL में एक वाक्य रचनात्मक रूप से मान्य तालिका नाम नहीं है। अन्य आरक्षित शब्दों के लिए भी यही सच होगा।

+0

प्रश्न का उत्तर देने के लिए लंबे समय से चलने वाले बग के लिए पीआर जारी करना - ब्रावो! – Peter

+0

यदि आप मेरे निश्चित संस्करण को डाउनलोड करने में बहुत जल्दी थे, तो मैंने एक और प्रतिबद्ध किया है जो डालने के बाद संसाधनों को साफ़ करने के लिए कोड की एक अतिरिक्त पंक्ति में जोड़ता है। यह सुनिश्चित नहीं है कि यह कितना महत्वपूर्ण है, लेकिन ऐसा करने के लिए समझदार लगता है और मूल 'डीबीआई :: dbWriteTable' में था। –

+2

@ हैडली के साथ चर्चा के बाद, मेरा फिक्स अब एक बहुत आसान एक-लाइनर है जो ऊपर वर्णित दूसरे अंक को ठीक करता है ('build_sql' के साथ 'paste0' को प्रतिस्थापित करता है)। 'डीबीआई :: डीबीड्राइटटेबल 'में आवश्यक परिवर्तन [जीएसबीबी संस्करण में' आरएसक्यूलाइट 'में किए गए हैं (https://github.com/rstats-db/RSQLite), हालांकि आपको [github संस्करण) की भी आवश्यकता होगी DBI] (https://github.com/rstats-db/DBI)। –