问题描述
我在 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"))
我在连接到远程数据库后尝试了这个简单的 dplyr 函数,但失败并显示错误消息。
day %>%
mutate(ovnprofit = ifelse(stockCode == lead(stockCode,1),lead(priceOpen,1)/priceClose,NA)) %>%
select(logDate,stockCode,ovnprofit)
我该如何解决这个问题?
附言当我首先将 'day' 转换为 tibble 后应用 dplyr 函数时,它起作用了。但是,我想直接应用 dplyr 函数,而不是转换为 tibble,因为它既耗时又占用内存。
解决方法
问题很可能出在 LEAD("stockCode",1.0,NULL) OVER ()
函数上。在 R 中,数据集有顺序,但在 SQL 中数据集是无序的,需要明确指定顺序。
注意错误信息中的SQL代码包含:
OVER
arrange
之后的括号中没有任何内容向我表明 SQL 期望这里有一些东西。
您可以通过两种方式解决此问题:
- 在变异前使用
order_by
- 通过指定
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)