I am writing the following code in R but it gives me an error
S=function(x,a){
if(x<=a) {return (g)}
else
if (a < x <= b) {return(h)}
> Error: unexpected '<=' in:
> "
> else if (a < x <="
> else (return(i))
> }
How do I correct it?
So, I have rewritten your function to compile and eval, but I have no idea what it does for your problem.
S=function(x, a, b){
if (x <= a){
return(a)
}
else if ((a < x) && (x <= b)){ # break up the compound into two tests
return(a)
}
else{
return(a)
}
}
You need to pass b and I don't know what h,g were, but they weren't being assigned in your function declaration.
> S(1,2,3)
[1] 2
Related
Let's suppose the next function:
demo_function <- function(x){
if(is.na(x)){
return(NA)
} else if(1 < x < 2){
return("something")
} else {
return("Nothing")
}
}
The idea is that when the argument x is between 1 and 2, say x=0.001, then the function returns something.
However when trying to run the above function, the next error arises:
Error: no function to go from, jumping to a higher level
How could I adjust the function in order to get "something" for the specified argument?
The issue is in the else if i.e. the syntax in R is different than the mathematical notation - multiple expressions are connected by logical operators
else if(1 < x && x < 2)
i.e.
demo_function <- function(x){
if(is.na(x)){
return(NA)
} else if(1 < x && x < 2){
return("something")
} else {
return("Nothing")
}
}
> demo_function(0.01)
[1] "Nothing"
> demo_function(1.5)
[1] "something"
> demo_function(NA)
[1] NA
I 'm trying to use else if within a function in R
new<-function(a,b,c,d){
if (a==1){
var1<-100+100+100
var2<-500+500+500
var3<-500-100
}else if (a==2){
var1<-100+100
var2<-500+500
var3<-500-10
} else if (a==3){
var1<-100
var2<-500
var3<-500
}
b<-var1-var2
c<- var2+var3
d<-var3-var1
if (b<100)
{print ("the value is good")
}else if (b>100)
{ print("check teh value")
}else
{print ("repeat")
}
}
output<-new(3,b,c,d)
I feel something fundamental is wrong with this which I m missing. I 'm trying to use else if to populate the values to be used as an input to call the same fucntion.
Help is greatly appreciated
You can simplify to:
new <- function(a) {
if (a == 1) {
b <- -1200
} else if (a == 2) {
b <- -800
} else if (a == 3) {
b <- -400
}
if (b < 100)
{
print ("the value is good")
} else if (b > 100)
{
print("check the value")
} else
{
print ("repeat")
}
return(b) # for fun return the value of b
}
output <- new(2)
But this function will always have the side effect of printing "the value is good" because b always evaluates to a negative number. What's the purpose?
If you would want to return values a to d, you could do the intermediate calculations as per your example and do: return(list(a = a, b = b, c = c, d = d)) instead of return(b).
This recursion code doesn't give an output for n > 2. It works if I include the last if condition as else. Why does this happen?
fib <- function(n){
if(n == 0){
0
}
if(n ==1 ){
1
}
if(n == 2){
1
}
if (n > 2) {
print(n)
fib(n-1) + fib(n-2)
}
}
A function by default returns the result of the last value evaluated inside the function. Here you have a bunch of separate if statements that will all be evaluated (your function doesn't return early at any point. Observe
f <- function(a) {
-99
if (a==1) {111}
if (a==2) {22}
}
f(1)
# -- doesn't return anything --
f(2)
# [1] 22
f(3)
# -- doesn't return anything --
When 'a==1', That middle if statement would evaluate to 111 but that value is then discarded when you run the next if statement just like the -99 value was before it. The last expression that was evaluated in this function is the if (a==2) {22} and that will either return 22 or it will return NULL. It won't return the previous values because it has no idea how those would be related without the else statement.
fib <- function(n){
if(n == 0){
return(0)
}
if(n ==1 ){
return(1)
}
if(n == 2){
return(1)
}
if (n > 2) {
print(n)
return(fib(n-1) + fib(n-2))
}
}
Or you could turn those into if/else staments so only one "thing" will be returned
fib <- function(n){
if(n == 0){
0
} else if(n ==1 ){
1
} else if(n == 2){
1
} else if (n > 2) {
print(n)
fib(n-1) + fib(n-2)
}
}
IS <- function(N,K,sigma,t,r,S_0,a,b,tol){
funct_1 <- function(x){
return((S_0*(exp(-0.5*(sigma^2)*t+sigma*sqrt(t)*x))*(sigma*sqrt(t)-x))+
(exp(-r*t))*K*x)
}
bisection_method <- function(a, b, tol, f = funct_1){
if (f(a)*f(b) > 0){
print("No root found.")
} else
while ((b - a)/2.0 > tol){
midpt= (a + b)/2.0
if (f(midpt) == 0){
return(midpt)
} else if (f(a)*f(midpt) < 0){
b = midpt
} else
a = midpt
}
return(midpt)
}
}
The above function will produce nothing for you. My goal that to input the values of "N,K,sigma,t,r,S_0, a,b" and somehow return "midpt" for me. I have searched a lot but could not come up with anything that makes sense. I have many problems, assume that I input everything things, then how the function "funct_1" will output expression, this expression needs to be recalled to the next function "bisection_method} along with the value of a and b then finally obtain the "midpt" value. Any suggestions are really appreciated. Please let me know if there is anything not clear to you at all.
Your main function doesn't return anything. It just creates the auxiliary functions and then do nothing. That's why you're getting no output.
Try returning the bisection method with appropriate parameters in your main function instead. I also edited so you get NULL output when no root is found.
IS <- function(N,K,sigma,t,r,S_0,a,b,tol){
funct_1 <- function(x){
return((S_0*(exp(-0.5*(sigma^2)*t+sigma*sqrt(t)*x))*(sigma*sqrt(t)-x))+
(exp(-r*t))*K*x)
}
bisection_method <- function(a, b, tol, f = funct_1){
if (f(a)*f(b) > 0){
print("No root found."); return(NULL)
} else
while ((b - a)/2.0 > tol){
midpt= (a + b)/2.0
if (f(midpt) == 0){
return(midpt)
} else if (f(a)*f(midpt) < 0){
b = midpt
} else
a = midpt
}
return(midpt)
}
return(bisection_method(a,b,tol,funct_1))
}
Figured out some parameter combination that makes sense:
IS(1,1,1,4,5,1,.1,9,10^-4)
[1] 2.000023
I created this simple code in R to solve the Knapsack program with a recursive funtion
n <- c(0,1,2,3,4)
v <- c(10,40,30,50)
w <- c(5,4,6,3)
k <- 10
myfunction <- function(n,k){
if (n==0 | k==0){
output <- 0
} else if (w[i] > k) {
output <- myfunction[i-1,w]
} else {
output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
}
return(myfunction)
}
However, I don't get a value as an output, but the whole function. For example if I put in:
myfunction(4,10)
I don't get an value of 90, but the whole funtion typed out.
these are the values
There were several errors beyond the ones pointed out by #etienne. Here's an annotated debugging session. First we fix the returned object:
> myfunction <- function(n,k){
+ if (n==0 | k==0){
+ output <- 0
+ } else if (w[i] > k) {
+ output <- myfunction[i-1,w]
+ } else {
+ output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
+ }
+ return(output)
+ }
> myfunction(4,10)
Error in if (w[i] > k) { : argument is of length zero
Obviously neither w nor k are of length zero which suggests it must be i. (As also pointed out by etienne). Looking at your code it appears you actually intended i to be the index that decreased until the terminating condition was met. So replace n by i in the few instances where it appeared:
> myfunction <- function(i,k){
+ if (i==0 | k==0){
+ output <- 0
+ } else if (w[i] > k) {
+ output <- myfunction[i-1,w]
+ } else {
+ output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
+ }
+ return(output)
+ }
> myfunction(4,10)
Error in myfunction[i - 1, w] :
object of type 'closure' is not subsettable
So you also made the mistake of using square-brackets where parentheses (aka bracket in the non-US sections of the world) were needed:
> myfunction <- function(i,k){
+ if (i==0 | k==0){
+ output <- 0
+ } else if (w[i] > k) {
+ output <- myfunction(i-1,w)
+ } else {
+ output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
+ }
+ return(output)
+ }
> myfunction(4,10)
[1] 90
Success, well, almost. Most of the warnings are because you used | instead of || in one of the conditionals:
Warning messages:
1: In if (i == 0 | k == 0) { :
the condition has length > 1 and only the first element will be used
2: In if (w[i] > k) { :
the condition has length > 1 and only the first element will be used
3: In if (i == 0 | k == 0) { :
the condition has length > 1 and only the first element will be used
4: In if (i == 0 | k == 0) { :
the condition has length > 1 and only the first element will be used
5: In if (i == 0 | k == 0) { :
the condition has length > 1 and only the first element will be used
6: In if (i == 0 | k == 0) { :
the condition has length > 1 and only the first element will be used
So replace that instance with a logical ||. To deal with the other warning that didn't seem to sabotage your logic, realize that w[i] is length-0 when i == 0, so add a logical clause in the conditional that first tests for that possibility and use the correct "double-AND-sign" ( && ):
myfunction <- function(i,k){
if (i==0 || k==0){
output <- 0
} else if (length( w[i]) && w[i] > k) {
output <- myfunction(i-1,w)
} else {
output <- max(v[i]+ myfunction(i-1, k-w[i]), myfunction(i-1,k))
}
return(output)
}
Now you get:
> myfunction(4,10)
[1] 90