Functions that make functions.
> log10
function (x) .Primitive("log10")
> changelog <- function(b) {
+ function(x) {
+ log(x)/log(b) }}
log10 <- changelog(10)
> log10(10)
[1] 1
> log10
function(x) {
log(x)/log(b)}
<environment: 0x000000000e46a9e8> #notice the environment
The enclosing environment of the
log10
is the execution environments of the
changelog
function when
log10
was defined by assignment.
There is however a ‘bug’ due to lazy evaluation so it is better to always force the function parameter.
> changelog <- function(b) {
+ force(b)
+ function(x) {log(x)/log(b)}
+ }
You can combine factories with functionals
> names <- list(log2 = 2,
+ log3 = 3,
+ log10 = 10)
> (logs <- purrr::map(names, changelog))
$log2
function(x) {log(x)/log(b)}
<bytecode: 0x000000000dbc6b98>
<environment: 0x000000000e03dc20>
> logs$log2(2)
[1] 1
> logs$log10(10)
[1] 1
> logs$log3(3)
[1] 1
You can use factories to pass different arguments according to your needs to other functions.
> n <- 100; sd <- c(1, 5, 15)
> df <- data.frame(x = rnorm(3*n, sd = sd), sd = rep(sd, n))
> histograms<-ggplot(df, aes(x)) +
+ geom_histogram(binwidth = 2) +
+ facet_wrap(∼ sd, scales = "free_x") +
+ labs(x = NULL)
> jpeg("histograms.jpeg")
> plot(histograms)
> dev.off()
null device
The code above creates
binwidth
facets in which the is the same, this is not ideal to compare the different histograms.
Output 1
we can create a variable bin width
> binwidth_bins <- function(n) {
+ force(n)
+ function(x) {
+ (max(x) - min(x)) / n
+ }
+ }
and then we run a new groups of histograms
> histograms2<-ggplot(df, aes(x)) +
+ geom_histogram(binwidth = binwidth_bins(20)) +
+ facet_wrap(∼ sd, scales = "free_x") +
+ labs(x = NULL)
> jpeg("histograms2.jpeg")
> plot(histograms2)
> dev.off()
null device
Now the
binwidth
varies and keeps constant the number of observations in each bin
Output 2