2015-01-25 5 views
20

Я программно выбираю набор наборов данных, многие из которых имеют глупые имена, которые начинаются с цифр и имеют в них специальные символы, такие как минусовые знаки. Поскольку ни один из наборов данных не является особо большим, и я хотел, чтобы преимущество R максимально приближалось к типам данных, я (ab) использовал dplyr, чтобы сбрасывать эти таблицы в SQLite.Имена таблиц с экранированными скобками с 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 обрабатывает квадратные скобки в некотором роде, что я не могу понять. Мое подозрение в том, что это ошибка, но я хотел сначала проверить здесь, чтобы убедиться, что я ничего не пропустил.

EDIT: Я забыл упомянуть случай, когда я просто передаю дьявольское имя непосредственно в 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

Это всего лишь предположение, но это может быть из-за соглашений об именах R. Один из возможных способов обхода, который я нашел, - использовать 'name = gsub (" [.] "," ", Make.names (" [14m3-n4m3] "))'. Если вы это сделали, вы все равно можете передать свои исходные имена в 'copy_to()', хотя они будут немного отличаться в данных. Не уверен, что это помогает, но это мои два цента.Очень хороший вопрос. –

+1

Это лучшее обходное решение, чем то, что я начинал с реализации. Медленно разговаривая с мыслью о том, что хорошие имена + другие неприятности> плохие имена. – Peter

+0

Я согласен с @RichardScriven - лучше изменить имена существующими инструментами, чем пытаться опрокинуть свои собственные! –

ответ

3

Это ошибка в dplyr. Он все еще присутствует в текущем github-хозяине. Как указывает @hadley, он попытался избежать таких вещей, как имена таблиц в dplyr, чтобы предотвратить эту проблему. Текущая проблема, с которой вы сталкиваетесь, возникает из-за отсутствия выхода из двух функций. Создание таблицы отлично работает при предоставлении не присвоенного имени таблицы (и выполняется с помощью dplyr::db_create_table). Однако вставка данных в таблицу выполняется с использованием DBI::dbWriteTable, который не поддерживает имена нечетных таблиц. Если имя таблицы предоставлено для этой функции, она не может найти ее в списке таблиц (первая ошибка, о которой вы сообщаете). Если он предоставлен с экранированным доступом, то SQL для выполнения вставки не является синтаксически действительным.

Вторая проблема возникает, когда таблица обновляется. Код для получения имен полей, на этот раз на самом деле в dplyr, снова не позволяет избежать имени таблицы, потому что он использует paste0, а не build_sql.

Я исправил обе ошибки на a fork of dplyr. Я также добавил запрос на удаление @hadley и сделал заметку по вопросу https://github.com/hadley/dplyr/issues/926. Тем временем, если вы захотите, вы можете использовать , а затем вернуться к основной версии, как только она будет исправлена.

Кстати, правильный SQL-99 способ избежать имен таблиц (и других идентификаторов) в SQL с двойными кавычками (см. SQL standard to escape column names?). MS Access использует квадратные скобки, а MySQL по умолчанию - обратные. dplyr использует двойные кавычки по стандарту.

И, наконец, предложение от @RichardScriven не будет работать повсеместно. Например, select является вполне допустимым именем в R, но не является синтаксически допустимым именем таблицы в SQL. То же самое можно сказать и о других зарезервированных словах.

+0

Выдает PR для давней ошибки, чтобы ответить на вопрос - браво! – Peter

+0

Если вы очень быстро загрузили мою исправленную версию, я сделал еще одну фиксацию, которая добавляет дополнительную строку кода для очистки ресурсов после вставки. Не уверен, насколько это важно, но кажется разумным делать и находилось в исходном «DBI :: dbWriteTable». –

+2

После обсуждения с @hadley мое исправление теперь является гораздо более простым однострочным шрифтом, который исправляет вторую проблему, описанную выше (заменяя 'paste0' на' build_sql'). Необходимые изменения в 'DBI :: dbWriteTable' были сделаны в [' RSQLite' в версии github] (https://github.com/rstats-db/RSQLite), хотя вам также понадобится версия [github DBI] (https://github.com/rstats-db/DBI). –

Смежные вопросы