问题描述
我打开了一个 issue for this。但是,如果这是操作员错误而不是包的问题,我会在此处发布以获取编码建议。
对 dbplyr
的最新 (v2.1) 更新旨在增加对 across
和相关函数的支持。但是,当我尝试使用它时仍然出现错误。
我应该使用不同的语法吗?有解决方法吗?
library(dplyr,warn.conflicts = FALSE)
library(bigrquery)
set.seed(02042021)
Sys.setenv(BIGQUERY_TEST_PROJECT = "elite-magpie-257717")
bq_deauth()
bq_auth(email="ariel.balter@gmail.com")
conn = DBI::dbConnect(
bigrquery::bigquery(),project = bq_test_project(),dataset = "test_dataset"
)
my_table = data.frame(
A = replicate(10,paste(sample(letters[1:3],3,replace=T),collapse="")),B = replicate(10,C = replicate(10,D = runif(10)
)
my_table
#> A B C D
#> 1 bcb cbb bbb 0.3620390
#> 2 aac aac bba 0.5505868
#> 3 aca abb bcb 0.4028455
#> 4 bca baa bbb 0.3247477
#> 5 bcc cac ccc 0.6861223
#> 6 cac bba baa 0.6970764
#> 7 bcb bbc acc 0.6873332
#> 8 bca acb acb 0.5391651
#> 9 cba ccc abc 0.9442450
#> 10 cca cbc bcc 0.6319561
my_table %>%
mutate(
has_ab = if_any(everything(),~grepl("ab",.))
)
#> A B C D has_ab
#> 1 bcb cbb bbb 0.3620390 FALSE
#> 2 aac aac bba 0.5505868 FALSE
#> 3 aca abb bcb 0.4028455 TRUE
#> 4 bca baa bbb 0.3247477 FALSE
#> 5 bcc cac ccc 0.6861223 FALSE
#> 6 cac bba baa 0.6970764 FALSE
#> 7 bcb bbc acc 0.6873332 FALSE
#> 8 bca acb acb 0.5391651 FALSE
#> 9 cba ccc abc 0.9442450 TRUE
#> 10 cca cbc bcc 0.6319561 FALSE
my_table %>%
mutate(
has_ab = if_any(where(is.numeric),.))
)
#> A B C D has_ab
#> 1 bcb cbb bbb 0.3620390 FALSE
#> 2 aac aac bba 0.5505868 FALSE
#> 3 aca abb bcb 0.4028455 FALSE
#> 4 bca baa bbb 0.3247477 FALSE
#> 5 bcc cac ccc 0.6861223 FALSE
#> 6 cac bba baa 0.6970764 FALSE
#> 7 bcb bbc acc 0.6873332 FALSE
#> 8 bca acb acb 0.5391651 FALSE
#> 9 cba ccc abc 0.9442450 FALSE
#> 10 cca cbc bcc 0.6319561 FALSE
dbRemoveTable(
conn=conn,name="test_dataset.mytable",value=my_table,overwrite=T
)
dbWriteTable(
conn=conn,overwrite=T
)
my_table_bq = tbl(conn,"mytable")
my_table_bq %>%
mutate(
has_ab = if_any(everything(),.))
)
#> Error in UseMethod("escape"): no applicable method for 'escape' applied to an object of class "formula"
my_table_bq %>%
mutate(
has_ab = if_any(where(is.numeric),.))
)
#> Error in UseMethod("escape"): no applicable method for 'escape' applied to an object of class "function"
由 reprex package (v1.0.0) 于 2021 年 2 月 5 日创建
解决方法
我认为目前使用 dbplyr(2.1.0 版)是不可能的。这是我的测试用例:
(1) 工作案例
# shared setup
library(dplyr)
library(dbplyr)
data(iris)
df = tbl_lazy(iris,con = simulate_mssql()) %>%
select(Sepal.Length)
df %>%
mutate(new = Sepal.Length + 1) %>%
show_query()
返回预期的 SQL:
<SQL>
SELECT `Sepal.Length`,`Sepal.Length` + 1.0 AS `new`
FROM `df`
(2) 介绍一个简单的一切
df %>%
mutate(new = if_any(everything(),TRUE)) %>%
show_query()
返回无效的 sql,因为不存在 if_any
或 everything
的翻译:
<SQL>
SELECT `Sepal.Length`,if_any(everything(),1) AS `new`
FROM `df`
(3) 简单的 is.numeric
df %>%
mutate(new = if_any(where(is.numeric),TRUE)) %>%
show_query()
错误,因为 is.numeric
作为函数传递
UseMethod("escape") 中的错误: 没有适用于“函数”类对象的“转义”方法
(4) 将 TRUE 包装在一个返回 TRUE 的函数中
df %>%
mutate(new = if_any(everything(),~{TRUE})) %>%
show_query()
错误,因为不存在隐式函数 ~{...}
的翻译:
UseMethod("escape") 中的错误: 没有适用于“公式”类对象的“转义”方法
,这里有一个基于 this answer 的关于动态 case_when
的潜在解决方法。
list_of_columns = colnames(df)
text_to_match = "ab"
cases = paste0("`",list_of_columns,"` %LIKE% '%",text_to_match,"%' ~ 1")
cases = c(cases,"1 == 1 ~ 0")
output = df %>%
mutate(new_col = case_when(
!!!rlang::parse_exprs(cases)
))
有关此技术的另一个示例,或作为可重用函数的一部分,请查看我的 dbplyr_helpers repo 的 collapse_indicator_columns
函数。