-
Notifications
You must be signed in to change notification settings - Fork 174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
across()
: Function evaluation seems to happen with no context / wrong context?
#1373
Comments
Somewhat more minimal reprex: library(dbplyr)
library(dplyr, warn.conflicts = FALSE)
power1 <- function(exp) {
force(exp)
function(x) x^exp
}
fns <- lapply(1:4, power1)
df <- lazy_frame(x = 1:10)
df |> summarize(across(x, fns))
#> <SQL>
#> SELECT
#> POWER(`x`, `exp`) AS `x_1`,
#> POWER(`x`, `exp`) AS `x_2`,
#> POWER(`x`, `exp`) AS `x_3`,
#> POWER(`x`, `exp`) AS `x_4`
#> FROM `df` Created on 2023-11-02 with reprex v2.0.2 I'm not sure dbplyr can do much here since it would require evaluating the bodies of functions in a way that I suspect is going to be very complex. Instead of relying on function scoping, you could instead generate functions that inline the value of library(rlang)
library(dbplyr)
library(dplyr, warn.conflicts = FALSE)
power1 <- function(exp) {
inject(function(x) x ^ !!exp)
}
fns <- lapply(1:4, power1)
df <- lazy_frame(x = 1:10)
df |> summarize(across(x, fns))
#> <SQL>
#> SELECT
#> POWER(`x`, 1) AS `x_1`,
#> POWER(`x`, 2) AS `x_2`,
#> POWER(`x`, 3) AS `x_3`,
#> POWER(`x`, 4) AS `x_4`
#> FROM `df` Created on 2023-11-02 with reprex v2.0.2 The downsidse of this technique is the generated functions don't have useful srcrefs so they don't look correct when you print them. I've filed r-lib/rlang#1665 to see if we can do better in rlang. |
Thank you @hadley for your workaround. Just one other thing that bothers me: If I inline library(rlang)
library(dbplyr)
library(dplyr, warn.conflicts = FALSE)
df <- lazy_frame(x = 1:10)
df |>
summarize(
across(
x,
lapply(
1:4,
function(exp) {
inject(function(x) x^!!exp)
}
)
)
)
#> Error in UseMethod("escape"): nicht anwendbare Methode für 'escape' auf Objekt der Klasse "function" angewendet Created on 2023-11-06 with reprex v2.0.2 |
The problem is when |
Hello,
Using
across()
together with a function factory that produces functions with some context information seems to produce incorrect SQL code.The reprex below also contains the dplyr version where everything works as expected:
across()
evaluates the functions within the correct context (in this case the variableexp
is from the context). Using a lazy tableexp
is not evaluated at all, and so all functions produce the same (incorrect) output.Created on 2023-10-05 with reprex v2.0.2
The text was updated successfully, but these errors were encountered: