Скользящее среднее, стандартное отклонение в dbplyr

Я хочу установить новую переменную с функцией прокрутки (скользящее среднее, стандартное отклонение и т. Д.) В dbplyr

Вот база данных

library(odbc)
library(DBI)
library(tidyverse)
library(zoo)

con <- DBI::dbConnect(odbc::odbc(),
                      Driver    = "SQL Server", 
                      Server    = "xx.xxx.xxx.xxx",
                      Database  = "stock",
                      UID       = "userid",
                      PWD       = "userpassword")

startday = 20150101
day = tbl(con, in_schema("dbo", "LogDay")) 

введите описание изображения здесь

Я хотел бы рассчитать скользящее среднее за 5 дней, вот мой код, но он не работает

Как я могу решить эту проблему?

library(zoo)    
day %>% 
      mutate(ma5 = rollmean(priceClose, k = 5, fill = NA))

error: nanodbc/nanodbc.cpp:1655: 42000: [Microsoft][ODBC SQL Server Driver][SQL Server]키워드 'AS' 근처의 구문이  [Microsoft][ODBC SQL Server Driver][SQL Server]문을 준비할 수 
    <SQL> 'SELECT TOP 11 "logNo", "stockCode", "logDate", "priceOpen", "priceHigh", "priceLow", "priceClose", "adjRate", "volume", "amount", "numListed", "remark", "marketCap", "foreignRate", "personNetbuy", "foreignNetbuy", "instNetbuy", "financeNetbuy", "insuranceNetbuy", "toosinNetbuy", "bankNetbuy", "gitaFinanceNetbuy", "pensionNetbuy", "gitaInstNetbuy", "gitaForeignNetbuy", "samoNetbuy", "nationNetbuy", rollmean("priceClose", 5.0 AS "k", NULL AS "fill") AS "ma5"
    FROM "dbo"."LogDay"
    WHERE ("logDate" > 20150101.0)
    ORDER BY "stockCode"'
    Warning : 
    Named arguments ignored for SQL rollmean

person Wookeun Lee    schedule 19.02.2021    source источник


Ответы (1)


Ошибка возникает из-за того, что rollmean не определен перевод dbplyr и не является командой SQL, которую можно использовать без перевода. Это неудивительно, поскольку rollmean является частью библиотеки data.table, а dbplyr фокусируется на переводе команд dplyr и base R.

Часть того, что вам нужно, - это оконная функция. dplyr имеет ряд оконных функций, как и SQL, но перевод между ними не всегда бывает . Но есть способы сделать это с помощью команд, для которых определены переводы.

Два возможных подхода к рассмотрению:

(1) сочетание отставания и опережения

df %>%
  mutate(prev2_price = lag(priceClose, 2, order_by = date),
         prev1_price = lag(priceClose, 1, order_by = date),
         next1_price = lead(priceClose, 1, order_by = date),
         next2_price = lead(priceClose, 2, order_by = date)) %>%
  mutate(ma5 = (prev2_price + prev1_price + priceClose + next1_price + next2_price) / 5)

Этот подход не будет хорошо масштабироваться, но он прост и понятен. Если вы хотите работать в группах (например, отдельные скользящие средние для каждой акции), примените group_by перед использованием lag и lead.

(2) объединять и отфильтровывать ненужные записи

df2 = df %>%
  select(stockCode, date, priceClose)

df %>%
  inner_join(df2, by = "stockCode", suffix = c("","_2") %>%
  filter(abs(date - date_2) <= 2) %>% # two records either side = window of width 5
  group_by(stockCode, date, priceClose) %>%
  summarise(ma5 = mean(priceClose_2)

Этот подход является гораздо более общим, но, возможно, его сложнее осмыслить.

person Simon.S.A.    schedule 19.02.2021
comment
Еще раз спасибо, Саймон. Я ценю вашу помощь. Поскольку функция прокрутки не поддерживается в dbplyr, я преобразовал таблицу в data.table, применил функцию прокрутки, и она сработала. - person Wookeun Lee; 20.02.2021