R recursive function call that works without stating arguments to function - r

The following simple recursion finds duplicated elements in a vector. It's taken from chapter 2 Functional Programming in R: Advanced Statistical Programming for Data Science, Analysis and Finance by Thomas Mailund. I wonder why it works when we call rest inside the function as it is calling a function without stating arguments.
Usually this would just return the function definition, but in the recursive function we don't need to and I wondered why.
I can see how this would work if we replaced rest in the function directly with find_duplicates(x, i + 1), but I am struggling to see why it works calling just the name which the function is attached to.
E.g if we define f<- function (x) x and call f it just returns the code function (x) x.
find_duplicates <- function(x, i = 1) {
if (i >= length(x)) return(c())
rest <- find_duplicates(x, i + 1)
if (x[i] == x[i + 1]) c(i, rest)
else rest
}

rest is not a function, it's the output of the function find_duplicates given arguments x and i+1.
So indeed it's the same to type rest or find_duplicates(x, i + 1) in the if clause, they're both values, not functions.

Related

What's the meaning of the (x) in the following passage?

During my free time R studying, I read this article on usage of return(). In there, I came across a function, of which one element's meaning escapes my technical background, please see below:
bench_nor2 <- function(x,repeats) { system.time(rep(
# without explicit return
(function(x)vector(length=x,mode="numeric"))(x),repeats)) }
I've played with the codes of the article, but the logic behind this tiny (x) (specifically, it's 2nd occurrence) in the 3rd line is unclear to me.
It's an anonymous function. If we unwrap the code
bench_nor2 <- function(x,repeats) { system.time(rep(
# without explicit return
(function(x)
vector(length=x,mode="numeric")
)(x),
repeats)) }
we can see that within the rep( ... ) call, the first argument is
(function(x)vector(length=x,mode="numeric"))(x)
Now, this is a curious way of putting it. But what you get is that function(x) vector(...) defines a one-liner function (which calls vector to create a numeric vector of length x). Wrapped in parenthesis (function(x) ...) returns the function, and then with (function(x) ...)(x) calls the anonymous function with argument x.
You would get the same result from:
my_vector <- function(y) vector(length=y, mode="numeric")
bench_nor2 <- function(x, repeats) {system.time(rep(my_vector(x), repeats))}

Function which is inside another function

x<-2, y<-4
sum.xy <- function(x){
function(y){x + y}
}
In the above code, I do not figure out why sum.xy() just give a non-numerical value, can anybody explain?
the ouput of any function in R is either inside return or if there is no return (like in your case) then the last "printed object" is returned. In your, the function sum.xy returns a function: namely the function function(y){x+y}.
You can test this like this:
x<-2; y<-4
sum.xy <- function(x){
function(y){x + y}
}
class(sum.xy)
class(sum.xy(7))
sum.xy(7)
So sum.xy(7) is actually a function which for given y returns y + 7.
If you write sum.xy(7)(4) then 7+4 is returned.
I also recommend that you take a look at this chapter of advanced R.

r function in function arguments + apply

I'm having troubles using several functions within the same one and calling the arguments generated. I'm using a more complicated function that can be simplified as followed:
func.essai <- function(x) {
g <- sample(seq(1,30), x)
i <- sample(x,1)
func.essai.2 <- function(y,i) {
z <- y+i
}
h <- sapply(g,func.essai.2(y,i))
}
sq <- seq(1,4)
lapply(sq, func.essai)
I'm using arguments that are generated at the beginning of func.essai (and that depend on x) as a fixed input for func.essai.2, here for i, and as a vector to go through on the sapply function, here for g. This code doesn't work as such -- it doesn't recognize y and/or i. How can I rewrite the code to do so?
I think the error you get is because of your use of sapply. This should work instead of your line containing sapply:
h <- sapply(g,func.essai.2, i)
See ?sapply, which tells you that you should provide additional arguments behind the function that you are applying.

why are these memoised functions different?

I see that if I use memoise on a function in two different ways, I get two different behaviours, and I'd like to understand why.
# Non Memoised function
fib <- function(n) {
if (n < 2) return(1)
fib(n - 2) + fib(n - 1)
}
system.time(fib(23))
system.time(fib(24))
library(memoise)
# Memoisation stragagy 1
fib_fast <- memoise(function(n) {
if (n < 2) return(1)
fib_fast(n - 2) + fib_fast(n - 1)
})
system.time(fib_fast(23))
system.time(fib_fast(24))
# Memoisation strategy 2
fib_not_as_fast <- memoise(fib)
system.time(fib_not_as_fast(23))
system.time(fib_not_as_fast(24))
Strategy 1, is really fast, as it reuses the recursive results, whereas stratagy 2 is only fast if the exact input has been seen before.
Can someone explain to me why this is?
I think that the reason is simple. In the slow case, the function fib_not_as_fast is memoised. Inside the function, fib is called, which is not memoised. To be more detailed: when you calculate fib_not_so_fast(24), inside the function you have fib(22) + fib(23). Both of these have not been memoised.
In fib_fast, however, you use the memoised version also in the recursion. So, in this case, fib_fast(24) needs to evaluate fib_fast(22) + fib_fast(23). Both these function calls have already happened, when you calculated fib_fast(23) and are thus memoised.
What does work is to memoise a function later, after it has been defined. So, simply redefining the function fib() as fib <- memoise(fib) will work.

Write a function that takes two arguments, x and n, and returns h(x, n). using FOR loop

I am trying to write a function in R that takes two arguments, x and n, and returns h(x, n); x=1
Does anyone know how to do this using a for loop?
The function I am working with is:
x^0 + x^1 + x^2...x^n
I have been working for a while on this and am not sure if I am doing this correctly.
Can anyone give me some guidance on how to do this problem.
Here is what I have..
n = seq(1,6, by = 1)
x = 1
h = function (x,n){
for (i in 0:n){
for( i in 1:n){
sum = sum +x^i
{
}}
h <- function( x, n ) sum( x^c(0:n) )
h( 1, 6 )
Loops are best avoided in R. First, you can use vectors in many situations; then, learn to use apply and friends (sapply, lapply etc.).
Do yourself a favor and use <- instead of = in assignments. It pays off in the long run.
Like in other programming languages, no need to declare the variables outside of the function (and anyways, since n is an argument to your function, your first assignment has no effect on the function)
Don't use seq() where a simple k:n will do.

Resources