I am finding inconsistency in recursive function examples, so I need help clarifying its workings.
This recursive function has the argument x value be returned along with function fracrec. This fracrec gets multiplied by the original value of x. The value of it is whatever the parenthesis gives x-1 . It repeats until it exits at x == 0. Meaning that the x portion and '*' of return is the "formula" and what is used for every round.
facrec <- function(x){
if(x==0){
return(1)
} else {
return(x*facrec(x-1))
}
}
Now take this next one and there isn't anything like x and ''. So I then look at it differently since myfibrec(5) gives '5'. Taking the absolute value of the first pass would be 4+3 and already surpassing 5 with more passes still to go. There isn't any formula to go off of, so I am having difficulty understanding how the 5 came about. In the above I used the formula to be 'x' and '', which I'll admit its odd and probably incorrect.
myfibrec <- function(n) {
if(n==1||n==2){
return(1)
}else{
return(myfibrec(n-1)+myfibrec(n-2))
}
}
In yet another one, below it treats the value in the argument as the formula. This gives 2,3,4,5,6,7,8,9,10.
function Count (integer N)
if (N <= 0) return "Must be a positive integer";
if (N >9 ) return "counting completed";
else return Count (N+1);
end function
Where are all the formulas or math calculations coming from in these recursive functions?
for 'facrec' google "factorial"
for 'myfibrec' google "Fibonacci"
last one seems to be java code, not R
Related
with this function you can calculate the fibonacci sequence with a recursive function, but i am not sure why this works, i marked at which position i struggled, can someone explain me this code?
fib <- function(n){
if (n == 0) return(0)
if (n == 1) return(1)
seq <- integer(n) # at this point i didnt understand much at all
seq[1:2] <- 1
calc <- function(n) {
if (seq[n] != 0) return(seq[n])
seq[n] <<- calc(n-1) + calc(n-2)
seq[n]
}
calc(n)
}
In the course of the recursive function evaluation, fib() ends up getting called many times with the same n. One way to make this computation faster is to use memoization, which saves a record of values for which the function has previously been called, and the return values. Using #AnoushArivanR's fib function:
system.time(fib(30))
## user system elapsed
## 3.987 0.000 3.987
library(memoise)
fib <- memoise(fib)
system.time(fib(30))
## user system elapsed
## 0.004 0.000 0.004
In fact, now that I look at your code above, I believe it's doing exactly this — but it's definitely hard to understand! (Your question might have been better received if you explained that this was what you're trying to do ...)
Note
This implementation of fib function has been cited from Mastering Software Development in R by Dr. Roger D. Peng who taught me so much and I am forever grateful to him.
As mentioned above this code is poorly written and has been unnecessarily complicated. Here is a more simpler version. We first check that the n value is not less than 0, then as the first two elements of the sequence are necessary for the series calculation to start (each element being the sum of two previous elements in the series) we set them as 0 and 1 for n == 1 and n == 2 respectively. Then we use recursion which is a technique that a function calls itself from its body creating a series of repetitive computations until the maximum number of n is reached. So for example for n == 3 the function calls it self by calling fib(1) and fib(2) both of which have already been set and so on. Then for fib(4) the function calls both fib(3) and fib(2). fib(2) is already set and fib(3) will be calculated by summing fib(2) and fib(1) and ...
I hope this explanation has helped you get your mind around the idea.
fib <- function(n){
stopifnot(n > 0)
if(n == 1) {
return(0)
} else if(n == 2) {
return(1)
} else {
fib(n - 1) + fib(n - 2)
}
}
fib(7)
8
But as some of the calculations are computed more than once for example both fib(6) and fib(5) calculate fib(4) the execution of the function gets slower. For the sake of optimization your code has saved every fib(n) output into and empty vector called seq so before any computation takes place it checks whether the value for seq[n] has already been computed or not. If so, it will be used and if not it will be computed again. This technique is called memoization and whenver a new seq[n] is calculated it will be the nth element of the seq vector and for this purpose we make use of <<- called complex assignment operator as we are modifying an object in the parent environment of the function.
I am new to R and this is my thoughts.
I did:
summm<- function(z){ x<- sample(6,12,replace = TRUE) z<- sum(x) }
I name this function as summm.
But when I type summm, I didn't get any result back.
How can I get some results?
Thank you for your time and for your help!
You perform a function call with <function_name>(<arguments>). If your function does not require input, define it with no formal arguments:
summm <- function() {
sum(sample(6, 12, replace = TRUE))
}
> summm()
[1] 46
As for "not getting return back": in your example, the last operation your function performs is assignment. This is because assignment returns an invisible value, and functions return the last evaluated expression. So the function returns an invisible value, which exists, but doesn't print to the console.
There is never any reason to perform assignment as the last operation in a function since the assignment is only valid within the scope of the function call.
I'm writing a code to solve a sudoku puzzle using a video found from YouTube that has coded the same algorithm through Python. This code requires three functions to
Find an empty square.
insert a number into the empty square.
Test whether this number is valid to solve the puzzle.
This is using a backtracking algorithm for the solver.
I am having an issue when calling the functions together where i get the error:
Error in free_squ(x) : argument "x" is missing, with no default
In addition: Warning message:
In if (empty_sq == FALSE) { :
the condition has length > 1 and only the first element will be used
Called from: free_squ(x)
This is confusing as I only get it when running thIS code. So I can write other functions to call the individual functions to analyse the argument inserted into the overlying function:
function1(argument){
function2(argument){
function3(argument){
***DO STUFF***}}}
Why for the following code does function within the main function not recognise the argument?
sudoku_solve <- function(x){
empty_sq <- free_squ(x) # Define a new object to give coordinates of empty square
if(empty_sq == FALSE){ # If no empty square can be found
return(x) # Return the matrix
} else{
empty_sq <- empty_sq # Pointless line kept for clarity
}
for(i in c(1:9)){ # Integers to insert into the found empty square
if(valid(x, i, empty_sq) == TRUE){ # can the intiger be placed in this square?
x[empty_sq[1], empty_sq[2]] = i # if i valid, insert into empty square
}
if(sudoku_solve()){ # are all i's valid?
return(TRUE) # All i's valid
} else{
x[empty_sq[1], empty_sq[2]] = 0 # reset the initial try and try again with another
}
}
return(FALSE)
}
I have named the sudoku puzzle 'puzzle', and call the function by the following:
sudoku_solve(puzzle)
I think in the following statement, you are not passing any value to the function and x does not have a default value either.
if(sudoku_solve()){ # are all i's valid?
return(TRUE) # All i's valid
}
Hence, although the argument is initially passed, when the function is called again after the loop, it is called without an argument. So you pass to free_sq(x) inside sudoku_solve(), and it gives an error.
empty_sq <- free_squ(x)
Make sure you are passing a value to sudoku_solve or else set the default value for x wither in sudoku_solve or in the free_squ class/function.
If my function has input (x,y,z) in R, I want to write a line of code which ensures data for x is of the right form.
i.e. x is just a real number rather than anything else such as a vector or a list. I assume the code would go something like
if ( ... ){stop("x must be a real number")}
I would like to know what goes inside of the bracket instead of ... ?
The reason is that if I write in a vector, the programme just take the first component of the vector as the input. R would give a warning about this, but I would like the programme to be stopped immediately.
If you want to "stop" if your argument is of length 1, and a real number
You could use stopifnot
foo <- function(x, y, z) {
stopifnot(length(x)==1L & is.numeric(x))
}
or perhaps
foo <- function(x, y, z){
if(!(length(x)==1L & is.numeric(x))) { stop("x must be a real number")}
}
stop allows you to specify the error message whereas stopifnot will return the condition that was tested. (Both have advantages)
The benefit of stopifnot is that it can tell you exactly which of multiple conditions failed.for example (noting that I am now feeding multiple expressions)
foo <- function(x, y, z) {
stopifnot(length(x)==1L , is.numeric(x))
}
foo('a')
# Error: is.numeric(x) is not TRUE
foo(c(1,2))
# Error: length(x) == 1L is not TRUE
I am trying to write a function which does different things, depending on the second argument. But I am getting an error all the time. Depending on the dimension of the matrix, the function should perform different tasks. Here is an example
x<-cbind(X1,X2,X3)
function<-function(x,hnrstr){
if (hnrstr<-1){
x<-data.frame(X1=x[1],X2=x[2],X3=x[3])
y<-x
y[ ,"X2","X3"]<- gsub(" {2, }"," ",y[ ,"X2","X3"])
}
if (hnrstr<-2){
x<-data.frame(X1=x[1],X2=x[2])
P<-x
}
if (hnrstr<-1){
x<-y
}
if (hnrstr<-2){
x<-P
}
return(x)
}
apply(x,c(3,3), function(x,1))
I am getting the error:
Error in drop && !has.j : invalid 'x' type in 'x && y'
hnrstr<-1 is assigning the value of 1 to hnrstr. You do not want this in an if statement. You either meant "test that hnrstr is less than minus one", in which case add some whitespace. hnrstr < -1, or you meant "test that hnrstr is equal to one", in which case use double equals, hnsstr == 1.
If X1, X2 and X3 are vectors, then x will be a matrix. That is, it has two dimensions. that means that later, after you've assigned y <- x (why do you need to do this?) y[ ,"X2","X3"]) doesn't make much sense because it implies that there are 3 dimensions, not two. This is what is causing the error. Did you mean y[, c("X2","X3")])?
gsub accepts a vector, so after you've changed the previous code, you also need to change the call to that function. Do you want to pass it the second column or the third column or both (one after the other)?
Those second if blocks look pointless. Have a think about how you can remove them.
if (hnrstr<-1){
x<-y
}
if (hnrstr<-2){
x<-P
}
You don't need a return statement at the end of the function. R automatically returns the last value that was calculated in the function.
As Colin said, don't try and call your function "function". That's just asking for trouble. Change the line
function <- function(x,hnrstr){