Использование оператора UPDATE в sqldf в R - PullRequest
0 голосов
/ 22 апреля 2020

Я знаю, что проще использовать base R для обновления значения, но я должен сделать это в sqldf. У меня есть фрейм данных, и я хочу обновить поле в зависимости от условий. Если для column2 задано значение «c», то обновите значение в column1.

column1 <- c(1,2,3,4)
column2 <- c("a","b","c","d")
temp <- data.frame(column1,column2)
sqldf("
      UPDATE temp
      set column1=100
      WHERE column2 ='c'
      ")

над кодом, приведенным выше, выдайте «фрейм данных с 0 столбцами и 0 строками» и предупреждающее сообщение «In result_fetch (res@ptr, n = n): SQL операторы должны быть выполнены с dbExecute () или dbSendStatement () вместо dbGetQuery () или dbSendQuery (). " В результате таблица никогда не обновляется / не изменяется.

Большое спасибо за ваше драгоценное время.

1 Ответ

2 голосов
/ 22 апреля 2020

Это известно и намеренно: sqldf никогда не пытается обновить объекты в среде. Он просто действует как канал, копируя данные в базу данных sqlite (temp) и выполняя запрос, и пакет никогда не собирается перезаписывать исходные объекты в вызывающей среде.

Справочный материал FAQ 8 в sqldf README :

Хотя фреймы данных, на которые ссылаются операторы SQL, переданные в sqldf, автоматически импортируются в SQLite, sqldf ничего не экспортирует из соображений безопасности. Таким образом, если вы обновляете таблицу с использованием sqldf, вы должны явно вернуть ее, как показано в примерах ниже.

Использование ваших данных:

sqldf(c("
       UPDATE temp
       set column1=100
       WHERE column2 ='c'
       ", "select * from main.temp"))
# Warning in result_fetch(res@ptr, n = n) :
#   SQL statements must be issued with dbExecute() or dbSendStatement() instead of dbGetQuery() or dbSendQuery().
#   column1 column2
# 1       1       a
# 2       2       b
# 3     100       c
# 4       4       d

(Вы можете спокойно проигнорировать это предупреждение, это потому, что первый оператор ничего не возвращает.)

Таким образом, чтобы фактически использовать это для обновления объекта на месте в вашей среде, вам нужно будет захватить вывод самостоятельно.

temp
#   column1 column2
# 1       1       a
# 2       2       b
# 3       3       c
# 4       4       d
temp <- suppressWarnings(sqldf(c("
      UPDATE temp
      set column1=100
      WHERE column2 ='c'
      ", "select * from main.temp")))
temp
#   column1 column2
# 1       1       a
# 2       2       b
# 3     100       c
# 4       4       d
...