оконная функция dbplyr для сгруппированных операций изменения

Я хотел бы использовать _1 _ / _ 2_ для создания агрегированной переменной на уровне группы. Вот суть команды:

q = tbl_copy %>% 
  group_by(group_var) %>%
  mutate(x_agg = min(x))

Но это приводит к следующей ошибке: Error: Window function `min()` is not supported by this database

Как ни странно, когда я использую глагол summarise(), min() работает нормально.

q = tbl_copy %>% 
  group_by(group_var) %>%
  summarise(x_agg = min(x))

q %>% show_query()
<SQL>
SELECT `group_var`, `x`, MIN(`x`) AS `x_agg`
FROM `my_table`
GROUP BY `group_var`

Что мне не хватает? Как использовать group_by() с mutate() в копии таблицы MySQL?

ОБНОВЛЕНИЕ: ВОСПРОИЗВОДИМЫЙ ПРИМЕР

> con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
> copy_to(con, mtcars)
> 
> mtcars2 <- tbl(con, "mtcars")
> mtcars2 %>%
+     select(mpg,cyl) %>%
+     group_by(cyl) %>%
+     mutate(mpg_min = min(mpg))
Error: Window function `min()` is not supported by this database

person ericgtaylor    schedule 11.07.2017    source источник


Ответы (1)


MySQL не поддерживает оконные функции, поэтому dbplyr не может перевести ваш код dplyr в SQL.

Когда вы работаете с базой данных MySQL, обычным обходным путем является использование вложенных SQL-запросов, таких как этот:

select yt.*, t.x_agg
from yourtable yt inner join (select group_var, min(x) as x_agg 
                              from yt 
                              group by group_var) t 
                    on yt.group_var = t.group_var

Вы можете отправить вышеуказанный запрос напрямую в MySQL с помощью dbGetQuery или перенести эту стратегию в код dplyr:

tbl_copy %>% 
  inner_join(tbl_copy %>% 
               group_by(group_var) %>%
               summarise(x_agg = min(x)), by = "group_var")

Также обратите внимание, что если ваша таблица достаточно мала, более прямой способ - делать все в памяти (я имею в виду: на стороне клиента, то есть в R).

person Scarabee    schedule 11.07.2017
comment
да, я понял. Разве не разумно ожидать, что dplyr запишет эти подзапросы программно в переводах SQL? Я много mutate() занимаюсь групповым mutate() и не хотел бы переписывать свой dplyr код с кучей left_join() операторов. своего рода поражение большей частью цели использования dplyr вместо реляционной БД. - person ericgtaylor; 12.07.2017
comment
Я согласен, что было бы хорошо, если бы dplyr мог об этом позаботиться! Но я не знаю, следует ли нам этого ожидать ... В любом случае, в какой-то момент вам всегда нужно писать тщательно оптимизированные SQL-запросы, и я не думаю, что это можно сделать с помощью автоматического перевода с другого языка (особенно с учетом того факта, что что каждая СУБД имеет собственную реализацию SQL). - person Scarabee; 12.07.2017