When I use magrittr to pass a value for x to the function below, it results in an unusable function. Why is this happening? I have version magrittr_1.5.
library(magrittr)
f <- function(x) { function(y) { x + y } }
# Case 1 (works)
f.5 <- f(5)
f.5(6) # returns 11
# Case 2 (works)
f.5 <- f(5)
6 %>% f.5 # returns 11
# Case 3 (fails)
f.5 <- 5 %>% f
6 %>% f.5 # Error in x + y (from 1) :
# non-numeric argument to binary operator
# Case 4 (fails)
f.5 <- 5 %>% f
f.5(6); # Same error as case 3
Here is a partial answer. First off, it is easy to make it work if you evaluate x
in the calling environment of the inner anonymous function,
library(magrittr)
f <- function(x) { x; function(y) x + y }
f.5 <- 5 %>% f
6 %>% f.5
# [1] 11
To investigate what is going wrong, see what x
is evaluating to,
f <- function(x) {
function(y) {
print(sprintf("x: %s.", toString(x)))
x + y
}
}
## the failing case
fails <- 5 %>% f
6 %>% fails
# [1] "x: function (y) \n{\n print(sprintf(\"x: %s\", toString(x)))\n x + y\n}, TRUE"
It is pointing the result of calling withVisible
on f
, which happens when a function, freduce
, is called (code). In the body of the pipe
function, there is a line,
body(magrittr:::pipe)[[2]][[3]][[10]]
# env[["freduce"]] <- freduce
where freduce
is made available (look at magrittr:::pipe
for full context).
If this line is modified to simply be the actual code in the function freduce
(ie. copying magrittr:::freduce
), it seems to work,
## Make a modified %>% operator
mypipe <- magrittr:::pipe
## Change that line
body(mypipe)[[2]][[3]][[10]] <- quote(
env[["freduce"]] <-
function(value, function_list) {
k <- length(function_list)
if (k == 1L) {
result <- withVisible(function_list[[1L]](value))
if (result[["visible"]])
result[["value"]]
else
invisible(result[["value"]])
} else {
Recall(function_list[[1L]](value), function_list[-1L])
}
}
)
## Redefine
`%>%` <- mypipe()
## Test (now it works?!)
fails <- 5 %>% f
6 %>% fails
# [1] "x: 5"
# [1] 11
So, this is a partial solution because I can't figure out why redefining freduce
in this way makes it work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With