Reputation: 3565
Edit:
The labelFormat
function is from the leaflet
package.
I would like to modify an argument inside the format
function that is inside the formatNum
function.
So from this:
labelFormat <- function (prefix = "", suffix = "", between = " – ", digits = 3,
big.mark = ",", transform = identity)
{
formatNum <- function(x) {
format(round(transform(x), digits), trim = TRUE, scientific = FALSE,
big.mark = big.mark)
}
function(type, ...) {
switch(type, numeric = (function(cuts) {
paste0(prefix, formatNum(cuts), suffix)
})(...), bin = (function(cuts) {
n <- length(cuts)
paste0(prefix, formatNum(cuts[-n]), between, formatNum(cuts[-1]),
suffix)
})(...), quantile = (function(cuts, p) {
n <- length(cuts)
p <- paste0(round(p * 100), "%")
cuts <- paste0(formatNum(cuts[-n]), between, formatNum(cuts[-1]))
paste0("<span title=\"", cuts, "\">", prefix, p[-n],
between, p[-1], suffix, "</span>")
})(...), factor = (function(cuts) {
paste0(prefix, as.character(transform(cuts)), suffix)
})(...))
}
}
I would like to have this:
labelFormat <- function (prefix = "", suffix = "", between = " – ", digits = 3,
big.mark = ",", transform = identity)
{
formatNum <- function(x) {
format(round(transform(x), digits), trim = TRUE, scientific = FALSE,
big.mark = big.mark, decimal.mark = ',')
}
function(type, ...) {
switch(type, numeric = (function(cuts) {
paste0(prefix, formatNum(cuts), suffix)
})(...), bin = (function(cuts) {
n <- length(cuts)
paste0(prefix, formatNum(cuts[-n]), between, formatNum(cuts[-1]),
suffix)
})(...), quantile = (function(cuts, p) {
n <- length(cuts)
p <- paste0(round(p * 100), "%")
cuts <- paste0(formatNum(cuts[-n]), between, formatNum(cuts[-1]))
paste0("<span title=\"", cuts, "\">", prefix, p[-n],
between, p[-1], suffix, "</span>")
})(...), factor = (function(cuts) {
paste0(prefix, as.character(transform(cuts)), suffix)
})(...))
}
}
See the new argument decimal.mark
inside the format
function.
But to do this, I would not like to redefine the labelFormat
function.
In Python there's something that I use quite similar to modify an argument inside a function. Let's suppose that we want to modify the default behaviour of json.dumps
:
import functools
import json
my_json_dumps = functools.partial(json.dumps, ensure_ascii=False)
Now I can call my_json_dumps
instead of using json.dumps
, this way I don't needed to define the whole function again.
My problem is a little different, because I need to modify an argument that is inside an inner function!
Upvotes: 0
Views: 117
Reputation: 206197
In this case labelFormat
returns a function that contains a reference to the environment where formatNum
is defined. Here we can create a wrapper to change that value
my_labelFormat <- function(...) {
fun <- labelFormat(...)
evalq(formatNum <- function(x) {
format(round(transform(x), digits), trim = TRUE, scientific = FALSE,
big.mark = big.mark, decimal.mark = ',')
}, environment(fun))
return(fun)
}
So we call the default labelFormat
function but them manipulate the environment to change the formatNum
function
Upvotes: 4
Reputation: 226087
It's not easy. There's no way I know of to call g()
from outside of f()
, since that function does not exist until after you call f()
and execute the first step. To see this, try the following:
debug(f)
f(1)
ls() ## shows 'number', the only object in the local environment
g() ## Error: could not find function g
<ENTER>
<ENTER>
g() ## prints 'Hi', because the function has now been defined
A super-cheesy way to get at the definition of g()
would be:
eval(body(f)[[2]])
g()
## "Hi"
This picks the second element out of the expression that defines the function, which happens to be the definition of g()
, and evaluates it in the current environment.
Upvotes: 1