I am writing a program in which I need a function to call a function that was determined in the period beforehand, which may again call the function that was determined before itself and so on. However, I am finding myself inable to implement this in R.
Here is a minimal example of what I am trying to do:
functions <- list()
functions[[1]] <- function(x){
x
}
for (i in 2:10)
{
functions[[i]] <- function(x){
functions[[i-1]](x) + x
}
}
So after running this script, what I would want to happen is that when I call functions[[10]](1) is that R determines the value the function would have had in period 9, for which it needs the value of the function in period 8 and so on and adds the input to it. (So obviously, the output should be 10).
The problem is that when I do this, the function calls itself infinitely. The list looks like this:
[[1]]
function (x)
{
x
}
[[2]]
function (x)
{
functions[[i - 1]](x) + x
}
[[3]]
function (x)
{
functions[[i - 1]](x) + x
}
(...)
So when I call functions[[10]](x), it evaluates to functions[[9]](x) + x, but functions[[9]] then keeps calling itself over and over again.
Is there anything I can do so that I force R to write the value of i - 1 into each element of the list, such that it would look as follows?
[[1]]
function (x)
{
x
}
[[2]]
function (x)
{
functions[[1]](x) + x
}
[[3]]
function (x)
{
functions[[2]](x) + x
}
(...)
Or is there any other way I could do what I am trying to do here?
(Obviously, in the above given example, I could just sum, but in the application I am trying to simulate here, this is not possible and I can't think of another way to do it other than having each function call the one before it).
Here you go
functions <- list()
functions[[1]] <- function(x){
x
}
for (i in 2:10)
{
functions[[i]] <- function(x,i){
functions[[i-1]](x) + x
}
formals(functions[[i]])$i <- i
}
functions[[10]](5)
# 50
Related
Is there a way to use a function-call to set up a collection of variables with new names?
What I'd like is something like the following:
helper <- function (x) {
y <<- x + 1
NULL
}
main <- function (x) {
helper(x)
return(y)
}
However, there are two problems with this:
the code means that y is defined in the global environment, which I don't want;
I'm also aware that the <<- operator is not kosher as far as CRAN is concerned.
Essentially I'd like to make my function main cleaner by passing a lot of the work it does to helper. Is there any legitimate way to do this for a package that I eventually want to be on CRAN?
I don't think your approach is in any way really sensible (why not use a List), but if you really want to do that, you can use assign to assign variables in arbitrary environments, e.g. the parent frame:
helper <- function(x) {
assign('y', x + 1, envir=parent.frame())
NULL
}
main <- function(x) {
helper(x)
return(y)
}
main(1)
# [1] 2
You can use the strategy to have helper returning a list with the calculated variables and then use them:
helper <- function (x) {
y <- x + 1
list(y = y)
}
main <- function (x) {
vars <- helper(x)
return(vars$y)
}
If you are going to use y often and don't want to always type var$s, you could assign it locally:
main <- function (x) {
vars <- helper(x)
y <- vars$y
return(y)
}
In contrast to assigning variables in arbitrary environments, this makes it way easier to reason what your code does.
I would like to have the following generic function, which
checks for thew allowedFormats (This works),
than executes the generic function base on the type of argument x (works)
evaluates the statements after the call of UseMethod() (does not work - as expected)
Now it states in the help for UseMethod
Any statements after the call to UseMethod will not be evaluated as UseMethod does not return.
So this is not surprising. But is there a way that I can achieve this, apart from defining an additional function validate_after() which calls validate() followed by cat(“Validation completed”)?
validate <- function (
x,
allowedFormats
) {
# Check arguments ---------------------------------------------------------
allowedFormats <- c("none", "html", "pdf", "word", "all")
if (!(report %in% allowedFormats)) {
stop("'report' has to be one of the following values: ", allowedFormats)
}
UseMethod("validate", x)
cat(“Validation completed”)
}
Define and call a nested generic
> validate <- function (x, allowedFormats) {
+ .validate <- function(x, allowedFormats) {
+ UseMethod("validate", x)
+ }
+ # Check arguments ---------------------------------------------------------
+ # ...
+ .validate(x, allowedFormats)
+ cat("Validation completed")
+ }
> validate.numeric <- function(x, allowedFormats) {
+ cat('Working...\n')
+ }
> validate(5, NA)
Working...
Validation completed
Depending on what you wish to achieve this might be feasible using the 'on.exit' command, as demonstrated below:
test <- function(x, ...){
if(!is.integer(x))
stop("wups")
on.exit(cat("'On exit' executes after UseMethod, but before the value is returned. x = ", x,"\n"))
UseMethod("test")
}
test.integer <- function(x, ...){
cat("hello i am in a function\n")
x <- x + 3
cat("I am done calculating. x + 3 = ",x,"\n")
return(x)
}
test(1:3)
hello i am in a function
I am done calculating. x + 3 = 4 5 6
'On exit' executes after UseMethod, but before the value is returned. x = 1 2 3
[1] 4 5 6
This is not necessarily a perfect solution. For example if one wished to perform some extra calculations on the methods result, the result is not propagated to the the generic function (as UseMethod does not return). A possible workaround could be to force feed a environment into the called method, to store results in.
I'm a bit surprised by R's behaviour in a very specific case. Let's say I define a function square that returns the square of its argument, like this:
square <- function(x) { return(x^2) }
I want to call this function within another function, and I also want to display its name when I do that. I can do that using deparse(substitute()). However, consider the following examples:
ds1 <- function(x) {
print(deparse(substitute(x)))
}
ds1(square)
# [1] "square"
This is the expected output, so all is fine. However, if I pass the function wrapped in a list and process it using a for loop, the following happens:
ds2 <- function(x) {
for (y in x) {
print(deparse(substitute(y)))
}
}
ds2(c(square))
# [1] "function (x) " "{" " return(x^2)" "}"
Can anybody explain to me why this occurs and how I could prevent it from happening?
As soon as you use x inside your function, it is evaluated, so it "stops being an (unevaluated) expression" and "starts being its resulting values (evaluated expression)". To prevent this, you must capture x by substitute before you use it for the first time.
The result of substitute is an object which you can query as if it was a list. So you can use
x <- substitute(x)
and then x[[1]] (the function name) and x[[2]] and following (the arguments of the function)
So this works:
ds2 <- function(x) {
x <- substitute(x)
# you can do `x[[1]]` but you can't use the expression object x in a
# for loop. So you have to turn it into a list first
for (y in as.list(x)[-1]) {
print(deparse(y))
}
}
ds2(c(square,sum))
## [1] "square"
## [1] "sum"
I came across this example in Advanced R by Hadley. My question is after defining the function, j(1) outputs the inner function definition as supposed to what j(1)() is outputting? Intuitively, I think j(1) should output [1] 1 2
Could anyone explain what's going on actually? What's the difference between j(1) and j(1)() ?
> j <- function(x) {
+ y <- 2
+ function() {
+ c(x,y)
+ }
+ }
> k <- j(1)
> k()
[1] 1 2
> j(1)
function() {
c(x,y)
}
<environment: 0x7fa184353bf8>
> j()
function() {
c(x,y)
}
<environment: 0x7fa18b5ad0d0>
> j(1)()
[1] 1 2
tl;dr In R, the return value of a function can also be a function. That's the case here. j(1) returns a function, whereas j(1)() returns a numeric vector.
The difference between j(1) and j(1)() is that j(1) outputs a function because that's the last value in the definition of j. Functions return their last expression (or the value found in a relevant return() call), which in this case is also a function. j(1)() is calling the last value of j, which is the function returned from it. It does not take an argument, so the empty parentheses () is the argument list for j(1)
It might become a bit more clear if we have a closer look at j and some of its properties.
j <- function(x) {
y <- 2
function() {
c(x, y)
}
}
The difference between the calls becomes quite apparent when we look at their classes.
class(j(1))
# [1] "function"
class(j(1)())
# [1] "numeric"
When you defined j, 2 is hard-coded into its return function as the second value of the vector returned from that function. We can see the precise return value of a call to j(1) with
library(pryr)
unenclose(j(1))
# function ()
# {
# c(1, 2)
# }
So a call to j(1)() (or k()) will deliver the vector c(1, 2). Similarly, if we call j(5), the return value of j(5)() is c(5, 2)
unenclose(j(5))
# function ()
# {
# c(5, 2)
# }
Hope that helps.
Credit to #Khashaa for mentioning the unenclose() function (comment deleted).
I am trying to produce different uniform numbers using the Lehmar random number generator. I believe I have done this but I have a problem in producing different numbers each time I execute this function. Below is the code I am trying to do and I will explain the problem further underneath it.
MODULUS <- 2147483647
MULTIPLIER <- 48271
put_Seed <- function(x)
{
x <- (if ( x > 0)
{
x%%MODULUS
}
else
{
1000*as.numeric(Sys.time())
}
)
}
T_val <- function(Rand)
{
Q <- floor(MODULUS / MULTIPLIER)
R <- MODULUS%%MULTIPLIER;
floor(MULTIPLIER*(Rand%%Q) - R*(Rand/Q))
}
New_Random_Seed <- function(T_value_i)
{
Random_Seed <- (if (T_value_i > 0)
{
T_value_i;
}
else
{
T_value_i + MODULUS
})
}
Random <- function(New_Seed)
{
New_Seed/MODULUS
}
uniform_num <- function(a, b, r)
{
a + (b - a) * r
}
Random_Seed <- put_Seed(123456789)
uni_num <- function(k)
{
Random_Seed <- put_Seed(k)
T_value <- T_val(Random_Seed)
Random_Seed <- New_Random_Seed(T_value)
uniform_num(0, 1, Random(Random_Seed))
}
test1 <- uni_num(Random_Seed)
test2 <- uni_num(Random_Seed)
test3 <- uni_num(Random_Seed)
#Results
#test1 = 0.05380306
#test2 = 0.05380306
#test3 = 0.05380306
What I am trying to do is whenever I run the uni_num function that each time, the Random_Seed gets updated and the uniform_num(0, 1, Random(Random_Seed)) line produces a random uniform number between 0 and 1 each time the function is executed. The code works for 1 repetition but if I try to use the function again the Random_Seed has not being updated and hence the function will produce the same random number as before. This is undesirable as I wish to produce different random number's each time by having the Random_Seed updated after each repetition. Forgive me if there is a simple solution but my head is wrecked from trying to find an answer. Cheers :)
In this function:
uni_num <- function(k)
{
Random_Seed <- put_Seed(k)
T_value <- T_val(Random_Seed)
Random_Seed <- New_Random_Seed(T_value)
uniform_num(0, 1, Random(Random_Seed))
}
The target of the assignment Random_Seed <- is in the environment of the function body, and not the global environment. Thus, when you make a second call, Random_Seed in the global environment has not been modified, and you get the same results.
To write to the global environment instead, use <<-:
Random_Seed <<- New_Random_Seed(T_value)
It looks like this is the only assignment that must be modified, as New_Random_Seed returns a value and doesn't require modification of this global object. In addition, the first assignment to Random_Seed in uni_num might as well be in the function body environment.
Note that it's bad form for a function to write to the global environment. There's always a better way. But this will work for your example code.