function is getting executed for a invalid argument - r

Below is the function created to format number.
format_number <- function(num, format_flag = "yes"){
if(format_flag == "yes"){
num <- paste0(num/100,"%")
} else if (format_flag == "no"){
num <- num
}
return(num)
}
However, when I execute format_number(3,2), the answer is 3. Basically it should show an error right? Because 2 is not a valid input. Please advice

2 is valid input. but in your function none of "if" statement will satisfied because 2!='yes' and 2!='no' , then the original value of 'num' will return which is 3.

Related

Checking if a character entry in a function is in set of vectors in R

Please, I am trying to print a message based on an entry of a user.
I am studying for a test and I want to create a function that If I type an specific article( variable character) It will check over a set of vectors and print a message.
ExpfromUS <- function(x){
x <- readline("Check if your articles could be import or export to US. Entry the type of article that you want to ship: ")
a <- c(x == CBOExUS)
b <- c(x == RQSVExUS)
e <- c(x == NATExUS)
for ( i in length(a == TRUE)){
if (a[i] == TRUE){
print("Ok, but just with Contractual basis only");
break; }
else{ for (i in length(b)){
if (b[i] == TRUE){
print("Ok, but with restrictions of quantity, size or value");
break;}
else{ for (i in length(c)){
if (e[i] == TRUE){
print("Sorry, but we are not able to ship your cargo at this moment");
break;}
else{ print("Please check your entry we could not find this article in our database")
}}
}
}
}
}
}
But always print the last message "Please check your entry we could not find this article in our database", what am I doing wrong? (Sorry this is a beginner level doubt).
Thanks for all who spend their time helping me.
Expanding my comment: I suspect that your indexing for all the for loops is (part) the problem. The current indexing is only going to cause one iteration since length(a == TRUE) will return a single integer. I suspect you wanted the numeric values where "a == TRUE" so you could output a message at that row. The which function returns numeric values corresponding to the index of "TRUE" values of a logical vector, so perhaps you wanted:
for ( i in which(a) ){
....}
else{ for (i in which(b)){
...}
else{ for (i in which(c)){
....}
Further note: When working with logical vectors it is rarely necessary to include == TRUE and is sometimes going to return unexpected results when the vector includes NA's, since NA is never == to anything.
Given what you have offered as values for those three vectors I now thin it should have been
{....
a <- x %in% CBOExUS # the c() not needed. This returns a logical vector
b <- x %in% RQSVExUS
e <- x %in% NATExUS
.....
THe %in% function allows you to test for multiple values. The == function is asking if there is complete equality, obviously unlikely. There still may these correction be other flaws, but we're still without a [MCVE] and so we still won't be able to offer tested coding.

argument is of length zero but is.null is false

I'm trying to check a range of numbers against some values in a dataset using for control
for(i in 20:28)
{
for(j in 1:52)
{
if (Test$Ferritin[j]<15 & Test$RHCc[j]<i)
{
Test$Status[j] = "TP"
}
}
}
But I keep getting the error
Error in if (Test$Ferritin[j] < 15 & Test$RHCc[j] < i) { : argument
is of length zero
I did check the condition using is.null, but it returns "False" in the answer.
Can someone explain what I could be doing wrong?
NULL is of length 0, but not all length zero vectors are NULL (you can confirm for yourself via is.null(numeric(0))). Check whether length(argument) == 0 instead.

Check each argument exists as an input in a function

I am trying to make a function which gets few inputs. I would like to know how to check the availability of my arguments . Here is my function:
MyFunction<-function(data,window,dim,option) {
}
First, I want to see if there is any argument , if no, print an error
is it correct to use
if ~nargin
error('no input data')
}
Then, I want to make sure that the second argument is also inserted
is it right to ask like this
if nargin < 2
error('no window size specified')
}
Then, I want to check if the third argument is empty , set it as 1
if nargin < 3 || isempty(dim)
dim<-1
}
you can use hasArg()
testfunction <- function(x,y){
if(!hasArg(x)){
stop("missing x")
}
if(!hasArg(y)){
y = 3
}
return(x+y)
}
>testfunction(y=2)
Error in testfunction(y = 2) : missing x
> testfunction(x=1,y=2)
[1] 3
> testfunction(x=1)
[1] 4
As #Ben Bolker said , missing is used to test whether a value was specified as an argument to a function. You can have different conditions in your R functions such as warning or stop.
In your case, I would do the following
MyFunction<-function(data,window,dim,option) {
if (missing(data))
stop("the first argument called data is missing")
if (missing(window))
stop("the second argument called window is missing")
if (missing(dim))
dim <- 1
if (missing(option))
stop("the second argument called option is missing")
}

R file.info not working in if statement

This line of code returns TRUE if the file exits or NA if the directory does not exist.
In this case the directory does not exist so this line returns
file.info("M:/T/2014/")[1,"isdir"]
[1] NA
Now I want to catch this case so I do:
if(file.info("M:/T/2014")[1,"isdir"] != TRUE){
print("there is no directory")
}
But I get an error:
Error in if (file.info("M:/T/2014")[1, "isdir"] != TRUE) { :
missing value where TRUE/FALSE needed
I also tried:
if(as.character(file.info("M:/T/2014")[1,"isdir"]) == "NA"){
print("there is no directory")
}
Can you advise what to do to put != TRUE or == "NA" in the if statement?
Thank you.
Try something like this using an is.na statement:
f <- file.info("M:/T/2014/")[1,"isdir"]
if(!is.na(f) && !f) print("there is no directory")
Perhaps, though, you want:
f <- file.info("M:/T/2014/")[1,"isdir"]
if(is.na(f) | !f) print("there is no directory")

Executing alternate cmds using R

Is it possible in R to do the following:
execute cmd1
if cmd1 generates error, proceed to:
execute cmd2
Thanks
try and/or tryCatch may be of use to you. Consider the super-simple toy example below:
# Our function just returns it's input as long as input is not negative otherwise an error is generated
f <- function(n) {
if( n < 0 )
stop("need positive integer")
return(n)
}
# Our alternative function to run if we get an error from the first function
f2 <- function(n) return( cat( paste( "You have a negative number which is" , n ) ) )
# Now we try to run it with `try`:
if( class( try( f(-1) , silent = TRUE ) ) == "try-error" )
f2(-1)
#You have a negative number which is -1
# And using the sophisticated `tryCatch()`
tryCatch( f(-1) , finally = f2(-1) )
#Error in f(-1) : need positive integer
#You have a negative number which is -1
The return value of try() is the value of the expression if it evaluates without error, otherwise an object of the class "try-error". In the first example we just check to see if an error was generated using comparing the class of the return value of try and execute f2() if an error was generated.
Note there are quite a few ways to handle this and I certainly wouldn't advocate either of these as being the best, but they should be a useful starting point for you to learn more about error handling.
Try this, err is the error message in the try block.
tryCatch(stop(),
error=function(err){
print(1)
print(err)
})
Depending on your use case, even simple short-circuiting of boolean operators might be enough. i.e., if your functions can return TRUE to indicate no-error and FALSE to indicate an error, then you can use the fact that || will only evaluate the RHS operand if the LHS operand evaluates to FALSE.
> doAwesomeStuff <- function() {cat("OMG, I'm awesome! <falls flat on face>\n"); FALSE}
> okDoNormalStuff <- function() {cat("OMG, I'm OK! :-)\n"); TRUE}
> doAwesomeStuff() || okDoNormalStuff()
OMG, I'm awesome! <falls flat on face>
OMG, I'm OK! :-)
[1] TRUE
But if doAwesomeStuff() works,
> doAwesomeStuff <- function() {cat("OMG, I'm awesome!\n"); TRUE}
> doAwesomeStuff() || okDoNormalStuff()
OMG, I'm awesome!
[1] TRUE

Resources