使用 dbplyr 删除包含 NA 的行
Dropping containing NA rows with dbplyr
这是我 运行 通过 dbplyr
进行一些 SQL 查询的方式
library(tidyverse)
library(dbplyr)
library(DBI)
library(RPostgres)
library(bit64)
library(tidyr)
drv <- dbDriver('Postgres')
con <- dbConnect(drv,dbname='mydb',port=5432,user='postgres')
table1 <- tbl(con,'table1')
table2 <- tbl(con,'table2')
table3 <- tbl(con,'table3')
table1 %>% mutate(year=as.integer64(year)) %>% left_join(table2,by=c('id'='id')) %>%
left_join(table3,by=c('year'='year'))
我想删除一些包含 NA 的行,然后 collect
我的最终 table 但找不到任何对 dbplyr 查询有用的东西。
我试图从 tidyr
和其他一些基本函数(complete.cases()
等)中传递 drop_na()
。你能建议我什么来实现我的目标吗?也欢迎将 SQL 查询(如 WHERE FOO IS NOT NULL
)通过管道传输到 dbplyr 查询。
提前致谢。
嗯,其实我还是没有得到满意的解决方案。我真正想做的是在不输入 SQL 查询的情况下删除 R 环境中包含 NA 的行,我认为 dbplyr
还不支持此功能。
然后我写了一些简单的代码来实现我的愿望;
main_query<-table1 %>% mutate(year=as.integer64(year)) %>% left_join(table2,by=c('id'='id')) %>%
left_join(table3,by=c('year'='year'))
colnames <- main_query %>% colnames
query1 <- main_query %>% sql_render %>% paste('WHERE')
query2<-''
for(i in colnames){
if(i == tail(colnames,1)){query2<-paste(query2,i,'IS NOT NULL')}
else{query2<-paste(query2,i,'IS NOT NULL AND')}
}
desiredTable <- dbGetQuery(con,paste(query1,query2))
是的,我知道它看起来并不神奇,但也许有人可以利用它。
尝试使用 !is.na(col_name)
作为过滤器的一部分:
library(dplyr)
library(dbplyr)
df = data.frame(my_num = c(1,2,3))
df = tbl_lazy(df, con = simulate_mssql())
output = df %>% filter(!is.na(my_num))
调用 show_query(output)
检查生成的 sql 给出:
<SQL>
SELECT *
FROM `df`
WHERE (NOT(((`my_num`) IS NULL)))
额外的括号是 dbplyr 进行翻译的一部分。
如果您想对多列执行此操作,请根据 答案尝试以下方法:
library(rlang)
library(dplyr)
library(dbplyr)
df = data.frame(c1 = c(1,2,3), c2 = c(9,8,7))
df = tbl_lazy(df, con = simulate_mssql())
colnames = c("c1","c2")
conditions = paste0("!is.na(",colnames,")")
output = df %>%
filter(!!!parse_exprs(conditions))
调用 show_query(output)
显示生成的查询中出现的两列:
<SQL>
SELECT *
FROM `df`
WHERE ((NOT(((`c1`) IS NULL))) AND (NOT(((`c2`) IS NULL))))
这是我 运行 通过 dbplyr
进行一些 SQL 查询的方式library(tidyverse)
library(dbplyr)
library(DBI)
library(RPostgres)
library(bit64)
library(tidyr)
drv <- dbDriver('Postgres')
con <- dbConnect(drv,dbname='mydb',port=5432,user='postgres')
table1 <- tbl(con,'table1')
table2 <- tbl(con,'table2')
table3 <- tbl(con,'table3')
table1 %>% mutate(year=as.integer64(year)) %>% left_join(table2,by=c('id'='id')) %>%
left_join(table3,by=c('year'='year'))
我想删除一些包含 NA 的行,然后 collect
我的最终 table 但找不到任何对 dbplyr 查询有用的东西。
我试图从 tidyr
和其他一些基本函数(complete.cases()
等)中传递 drop_na()
。你能建议我什么来实现我的目标吗?也欢迎将 SQL 查询(如 WHERE FOO IS NOT NULL
)通过管道传输到 dbplyr 查询。
提前致谢。
嗯,其实我还是没有得到满意的解决方案。我真正想做的是在不输入 SQL 查询的情况下删除 R 环境中包含 NA 的行,我认为 dbplyr
还不支持此功能。
然后我写了一些简单的代码来实现我的愿望;
main_query<-table1 %>% mutate(year=as.integer64(year)) %>% left_join(table2,by=c('id'='id')) %>%
left_join(table3,by=c('year'='year'))
colnames <- main_query %>% colnames
query1 <- main_query %>% sql_render %>% paste('WHERE')
query2<-''
for(i in colnames){
if(i == tail(colnames,1)){query2<-paste(query2,i,'IS NOT NULL')}
else{query2<-paste(query2,i,'IS NOT NULL AND')}
}
desiredTable <- dbGetQuery(con,paste(query1,query2))
是的,我知道它看起来并不神奇,但也许有人可以利用它。
尝试使用 !is.na(col_name)
作为过滤器的一部分:
library(dplyr)
library(dbplyr)
df = data.frame(my_num = c(1,2,3))
df = tbl_lazy(df, con = simulate_mssql())
output = df %>% filter(!is.na(my_num))
调用 show_query(output)
检查生成的 sql 给出:
<SQL>
SELECT *
FROM `df`
WHERE (NOT(((`my_num`) IS NULL)))
额外的括号是 dbplyr 进行翻译的一部分。
如果您想对多列执行此操作,请根据
library(rlang)
library(dplyr)
library(dbplyr)
df = data.frame(c1 = c(1,2,3), c2 = c(9,8,7))
df = tbl_lazy(df, con = simulate_mssql())
colnames = c("c1","c2")
conditions = paste0("!is.na(",colnames,")")
output = df %>%
filter(!!!parse_exprs(conditions))
调用 show_query(output)
显示生成的查询中出现的两列:
<SQL>
SELECT *
FROM `df`
WHERE ((NOT(((`c1`) IS NULL))) AND (NOT(((`c2`) IS NULL))))