dplyr 函数可以与 SQL Server 连接吗?

问题描述

我在 sql server 数据库中有一个表,我想用 R 包中的 dbplyr/dplyr 操作这个表。

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

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")) 

enter image description here

我在连接到远程数据库后尝试了这个简单的 dplyr 函数,但失败并显示错误消息。

day %>% 
  mutate(ovnprofit = ifelse(stockCode == lead(stockCode,1),lead(priceOpen,1)/priceClose,NA)) %>% 
  select(logDate,stockCode,ovnprofit)

enter image description here

我该如何解决这个问题?

附言当我首先将 'day' 转换为 tibble 后应用 dplyr 函数时,它起作用了。但是,我想直接应用 dplyr 函数,而不是转换为 tibble,因为它既耗时又占用内存。

解决方法

问题很可能出在 LEAD("stockCode",1.0,NULL) OVER () 函数上。在 R 中,数据集有顺序,但在 SQL 中数据集是无序的,需要明确指定顺序。

注意错误信息中的SQL代码包含:

OVER

arrange 之后的括号中没有任何内容向我表明 SQL 期望这里有一些东西。

您可以通过两种方式解决此问题:

  1. 在变异前使用 order_by
  2. 通过指定 lead# approach 1: day %>% arrange(logDate) %>% mutate(ovnprofit = ifelse(stockCode == lead(stockCode,1),lead(priceOpen,1)/priceClose,NA) ) %>% select(logDate,stockCode,ovnprofit) # approach 2: day %>% mutate(ovnprofit = ifelse(stockCode == lead(stockCode,1,order_by = 'logDate'),order_by = 'logDate')/priceClose,ovnprofit) 参数
lead

但是,您似乎也只想在每个股票代码中group_by。这可以通过 output = day %>% group_by(stockCode) %>% arrange(logDate) %>% mutate(next_priceOpen = lead(priceOpen,1)) %>% mutate(ovnprofit = next_priceOpen / priceClose) select(logDate,ovnprofit) 来完成。我会推荐以下内容:

show_query(output)

如果您使用 OVER 查看生成的 SQL,您应该看到类似于以下内容的 SQL LEAD(priceOpen,NULL) OVER (PARTITION BY stockCode ORDER BY logDate) 子句:

import bisect
bisect.bisect_left([1,2,3],2)