dplyr 函数可以连接 SQL 服务器吗?
Can dplyr function work connected with SQL server?
我在 SQL 服务器数据库中有一个 table,我想在 R 包中用 dbplyr/dplyr 操作这个 table。
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)
我该如何解决这个问题?
p.s。当我先将 'day' 转换为 tibble 后应用 dplyr 函数时,它起作用了。但是,我想直接应用 dplyr 函数,而不是转换为 tibble,因为它既耗时又占用内存。
问题很可能与 lead
函数有关。在 R 中,数据集有顺序,但在 SQL 中,数据集是无序的,需要明确指定顺序。
请注意,错误消息中的 SQL 代码包含:
LEAD("stockCode", 1.0, NULL) OVER ()
在 OVER
之后的括号中没有任何内容向我暗示 SQL 在这里需要一些东西。
解决此问题的两种方法:
- 通过在 mutate
之前使用 arrange
- 通过指定
lead
的 order_by
参数
# 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'),
lead(priceOpen,1, order_by = 'logDate')/priceClose,
NA)
) %>%
select(logDate,stockCode, ovnprofit)
但是,您似乎只想 lead
每个股票代码。这可以通过 group_by
来完成。我会推荐以下内容:
output = day %>%
group_by(stockCode) %>%
arrange(logDate) %>%
mutate(next_priceOpen = lead(priceOpen, 1)) %>%
mutate(ovnprofit = next_priceOpen / priceClose)
select(logDate,stockCode, ovnprofit)
如果您使用 show_query(output)
查看生成的 SQL,您应该会看到类似于以下内容的 SQL OVER
子句:
LEAD(priceOpen, 1.0, NULL) OVER (PARTITION BY stockCode ORDER BY logDate)
我在 SQL 服务器数据库中有一个 table,我想在 R 包中用 dbplyr/dplyr 操作这个 table。
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)
我该如何解决这个问题?
p.s。当我先将 'day' 转换为 tibble 后应用 dplyr 函数时,它起作用了。但是,我想直接应用 dplyr 函数,而不是转换为 tibble,因为它既耗时又占用内存。
问题很可能与 lead
函数有关。在 R 中,数据集有顺序,但在 SQL 中,数据集是无序的,需要明确指定顺序。
请注意,错误消息中的 SQL 代码包含:
LEAD("stockCode", 1.0, NULL) OVER ()
在 OVER
之后的括号中没有任何内容向我暗示 SQL 在这里需要一些东西。
解决此问题的两种方法:
- 通过在 mutate 之前使用
- 通过指定
lead
的
arrange
order_by
参数
# 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'),
lead(priceOpen,1, order_by = 'logDate')/priceClose,
NA)
) %>%
select(logDate,stockCode, ovnprofit)
但是,您似乎只想 lead
每个股票代码。这可以通过 group_by
来完成。我会推荐以下内容:
output = day %>%
group_by(stockCode) %>%
arrange(logDate) %>%
mutate(next_priceOpen = lead(priceOpen, 1)) %>%
mutate(ovnprofit = next_priceOpen / priceClose)
select(logDate,stockCode, ovnprofit)
如果您使用 show_query(output)
查看生成的 SQL,您应该会看到类似于以下内容的 SQL OVER
子句:
LEAD(priceOpen, 1.0, NULL) OVER (PARTITION BY stockCode ORDER BY logDate)