Non-execution of statement in function calling - r

While working on some problem i came across a situation in which i wanted to know if a function was executed when called upon. To do so i put a print statement in the function.
abc = function(x)
if(x > 0) {
return(x)
print("Go")
} else {
return(0)
print("Run")
}
y = abc(3)
y
# [1] 3
Why print statement is not executed while calling abc()?

That is because you are returning before printing. Change the sequence of those two statements and it should print
abc = function(x) {
if(x > 0) {
print("Go")
return(x)
} else {
print("Run")
return(0)
}
}
abc(3)
#[1] "Go"
#[1] 3
abc(-3)
#[1] "Run"
#[1] 0

Related

how to define a rank of values for an argument inside a function?

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

While Loop Inside For Loop in r

I expect the given code to output the answer : 1. However the loop runs forever. I am trying to see if while loop works for such a case. The use of while loop is necessary for the solution.
a = list(1,2,3,4)
for(i in a){
while(i != 2){
print(i)
}
}
Here are two solutions that work with while. The first one with a 'flag' set as TRUE, and the index as 1, based on the condition, set the 'flag' to FALSE
flag <- TRUE
i <- 1
while(flag) {
print(a[[i]])
i <- i + 1
if(a[[i]] == 2) {
flag <- FALSE
}
}
#[1] 1
Or we add a break
i <- 1
while(TRUE) {
print(a[[i]])
i <- i + 1
if(a[[i]] == 2) {
break
}
}
#[1] 1
The value of i does not change inside the while loop, so you never advance to the next item in list. You need if instead of while:
a = list(1,2,3,4)
for(i in a){
if(i != 2){
print(i)
}
}

IF ELSE function works in simple case, but my expanded function does not

I am trying to create functions that evaluates numbers and adds them to a category dependent on set criteria.
I wrote a "stupid" function with a lot of repetitions and lines, that can solve the job in a simple case:
# Findgroup (Everything manually typed out)
# Purpose of function:
#If 1 or 2: output A
#If 3 or 4: output B
#If 5 or 6: output random A/B (bonus if this can be balanced equally over the dataset)
# Else output "error"
findGroup <- function(x){ if (x == 1) {
"A"
} else if (x == 2) {
"A"
} else if (x == 3) {
"B"
} else if (x == 4) {
"B"
}else if (x == 5) {
sample(c("sA","sB"),1)
}else if (x == 6) {
sample(c("sA","sB"),1)
} else {
"Error"
}}
# Brief test: All matches expectations
findGroup(1) # Returns A
findGroup(3) # Returns B
findGroup(5) # Samples
findGroup(7) # Returns Error
This is okay, if I had to evaluate a few numbers. But what should I do if the list of numbers is much more elaborate? I tried to write a function that solves this in fewer lines, but the result does not work:
# Findgroup new
# Purpose of function:
#If 2:8: output A
#If 10:16: output B
#If 1,9: output random A/B (bonus if this can be balanced equally)
findGroupNew <- function(x){ if (x == 2|3|4|5|6|7|8) {
"A"
} else if (x == 10|11|12|13|14|15|16) {
"B"
} else if (x == 1||9) {
sample(c("sA","sB"),1)
} else {
"Error"
}}
# Brief test: All return A!!!
findGroupNew(1) # Should sample
findGroupNew(3) # Should Return A
findGroupNew(11) # Should Return B
findGroupNew(17) # Should Return Error
It may be a stupid mistake such as not having used the right sign for OR, but having tried solutions such as using || and & has not been successful.
I hope there is a quick fix to this issue and will appreciate your feedback.
Use %in% to check for multiple values.
findGroupNew <- function(x) {
if (x %in% 2:6) {
return("A")
} else if (x %in% 10:16) {
return("B")
} else if (x %in% c(1, 9)) {
return(sample(c("sA","sB"),1))
} else {
return("Error")
}
}
findGroupNew(1)
#[1] "sB"
findGroupNew(3)
#[1] "A"
findGroupNew(11)
#[1] "B"
findGroupNew(7)
#[1] "Error"

Question regarding R code to do with rounding prime numbers

I need to have a function where if a number entered is a prime number, it must round it up to the next prime number and if it is not to round it down to the previous prime number.
I have this code to identify whether it is a prime number:
prime <- function(x) {
if (x == 2) {
print(3)
} else if (any(x %% 2:(x-1) == 0)) {
FALSE
} else {
TRUE
}
}
I want to add a while loop to the true and false where if the function is false, it must minus one until it is true and if it is true, it must add one until it is true again but I am not sure how to do this.
Using your prime checker,
prime <- function(x) {
if (x == 2) {
print(3)
} else if (any(x %% 2:(x-1) == 0)) {
FALSE
} else {
TRUE
}
}
We build the new function, we first check if our number is a prime, if so, add 1 until we reach the next prime. If it is not a prime, we minus 1 until it is.
new <- function(x){
if (isTRUE(prime(x))){
x = x+1
while(prime(x) == FALSE){
x = x+1
}
return(x)
} else {
while(prime(x) == FALSE){
x = x-1
}
return(x)
}
}
we get
> new(7)
[1] 11
> new(10)
[1] 7

Test if an unevaluated promise exists

I has the following function:
f <- function(a, b=list()) {
if(exists("b")) {
if(exists("x",b)){
a+b[["x"]]
} else {
a
}
} else {
-a
}
}
And it's work, except when I put a undefined value for b:
exists("tmp")
# [1] FALSE
f(a = 1, b=tmp)
# Error in exists("x", b) : object 'tmp' not found
Is there a function to check if the promise value exists inside my function f?
What about something like this.
f <- function(a, b=list()) {
tryCatch(force(b), error=function(e) b<<-NULL)
if(!is.null(b)) {
if(exists("x",b)){
a+b[["x"]]
} else {
a
}
} else {
-a
}
}
f(5, tmp)
# [1] -5
f(5, list(x=3))
# [1] 8
f(5, list(z=3))
# [1] 5
Here we force evaluation of the parameter to see if it exists or resolves to something within a tryCatch() expression to handle the case where the variable does not exist. If it doesn't exist, we set it to NULL to make the rest of the function easier to work with.

Resources