I have to create a function which will detect if there is any non numeric value present in input. For this I have written this code
test<-function(x){
if(is.numeric(x)){
return(T)
}else{
return(F)
}
}
However when I test it with say
> test(a123)
Error in test(a123) : object 'a123' not found
But it works when i use quotes
> test("a123")
[1] FALSE
However I want it working in the first form. Any help on this will be greatly appreciated
test(a123) will not work. You have to store the user input in a object first and then pass it to your function.
Note that with your function test(123) also returns FALSE! (even if you insert deparse(substitute(x)) as suggested in the comments)
A shorter and correct way to perform your test is grep("[^0-9]", x) that returns 1 if the string x contains anything that is not a digit, 0 if not.
If you really want to have your function to work in what you refer to as the 1st form (but I think it is not a good idea as it can't receive any object and doesn't seem to have any use in an R script) :
test<-function(x){
x<-deparse(substitute(x))
grep("[^0-9]",x)
}
> test(123)
integer(0)
> test(a123)
[1] 1
Related
I need help on returning a value/object from function
noReturnKeyword <- function(){
'noReturnKeyword'
}
justReturnValue <- function(){
returnValue('returnValue')
}
justReturn <- function(){
return('justReturn')
}
When I invoked these functions: noReturnKeyword(), justReturnValue(), justReturn(), I got output as [1] "noReturnKeyword", [1] "returnValue", [1] "justReturn" respectively.
My question is, even though I have not used returnValue or return keywords explicitly in noReturnKeyword() I got the output (I mean the value returned by the function).
So what is the difference in these function noReturnKeyword(), justReturnValue(), justReturn()
What is the difference in these words returnValue('') , return('')? are these one and the same?
When to go for returnValue('') and return('') in R functions ?
In R, according to ?return
If the end of a function is reached without calling return, the value of the last evaluated expression is returned.
return is the explicite way to exit a function and set the value that shall be returned. The advantage is that you can use it anywhere in your function.
If there is no explicit return statement R will return the value of the last evaluated expression
returnValueis only defined in a debugging context. The manual states:
the experimental returnValue() function may be called to obtain the
value about to be returned by the function. Calling this function in
other circumstances will give undefined results.
In other words, you shouldn't use that except in the context of on.exit. It does not even work when you try this.
justReturnValue <- function(){
returnValue('returnValue')
2
}
This function will return 2, not "returnValue". What happened in your example is nothing more than the second approach. R evaluates the last statement which is returnValue() and returns exactly that.
If you use solution 1 or 2 is up to you. I personally prefer the explicit way because I believe it makes the code clearer. But that is more a matter of opinion.
This question is only for curiosity. My colleague and I were trying to write a function which returns NULL, but doesn't print it.
Before we found return(invisible(NULL)), I tried return({dummy<-NULL}) which works, but only once. After the first evaluation, the functions starts printing again:
test <- function() {
return({x<-NULL})
}
# no printout
test()
# with printout
test()
# with printout
test()
How does this come about?
I think this is due to some older return handling built into R. There are many return functions, withVisible, invisible, etc. When you return an assignment x<-null inside the return function it will not automatically print. If you want an assignment to print...
test <- function() {
withAutoprint(x<-NULL)
}
# with printout this time
test()
# with printout
test()
# with printout
test()
I think this just may be hard coded into the return function, maybe pulling something from this logic below, just a shot in the dark though.
Source: R Documentation
x <- 1
withVisible(x <- 1) # *$visible is FALSE
x
withVisible(x) # *$visible is TRUE
Again if we do not use an expression and simply return a variable or value inside our return function we get automatic printing. The reason I am guessing it returns on a second call has to do with the fact x was already assigned previously.
EDIT: I found this deep into the documentation on auto printing. "Whether the returned value of a top-level R expression is printed is controlled by the global boolean variable R_Visible. This is set (to true or false) on entry to all primitive and internal functions based on the eval column of the table in file src/main/names.c: the appropriate setting can be extracted by the macro PRIMPRINT."(Source)
I just tracked down a silly bug in some R code that I had written. The bug was equivalent to this:
brokenEarlyReturn = function(x=TRUE) {
if (x) return # broken with bare return
stop("Should not get here if x is TRUE. x == ", x)
}
brokenEarlyReturn(TRUE)
# Error in brokenEarlyReturn(TRUE) :
# Should not get here if x is TRUE. x == TRUE
The problem is that instead of return() I had just a bare return without the following parentheses. This causes the if statement be roughly equivalent to if (x) constant, where the body is a bareword that performs no action. In this case, the bareword is the definition of the return function itself, and the function continues rather than returning. The correct version would look like this:
workingEarlyReturn = function(x=TRUE) {
if (x) return() # parentheses added to return
stop("Should not get here if x is TRUE. x == ", x)
}
It makes sense that R requires parentheses after return, but as a C programmer I'm likely to occasionally forget to add them. Usually there would be a parsing error if they are omitted, but in this case of a bare return in the body of an if statement there is not.
Assuming I want the ability to put a "guard" statement at the top of a function that will return without a value if some condition is not met, how I can avoid making this error in the future? Or at least, how can I make it easier to track down this error when I do make it? Is there some "expression has no effect" warning that I can turn on?
I want to return my error message if arguments passed to the function are not of the required type (character)
if (!typeof(param1) == "character" || !typeof(param2) == "character") {
stop("You must provide valid arguments")
}
This only works if I provide invalid arguments. How can I ensure the message is displayed if some of the parameters are missing, because if doesn't work if I call the function without any parameters ?
You can use missing() to check whether an argument is provided. This is very much preferred over the other answers that suggest using default values that are of a different type than what expected (how confusing!). Only use defaults when it makes sense to have a default.
Also, it is not a good idea to use typeof() for type checking, in general. The typeof() function returns how the data are stored in the R implementation. Usually, a function cares whether an object presents a particular API, which corresponds to the class. To check inheritance, use is(). But in this case, for both readability and just to follow conventions, consider using is.character().
So you might have something like:
if (missing(param1) || !is.character(param1)) {
stop("'param1' must be provided as a character vector")
}
Also, things to keep in mind when checking vectors:
Often we really are expecting a scalar, i.e., a length-one vector, but a vector can have arbitrary length, so we should check that it is of length one.
Vectors can contain missing values, which code often cannot handle, so we often need to ensure that the values are not missing.
You might find it useful to define helpers for this, such as this function from the S4Vectors package in Bioconductor:
isSingleString <- function (x)
{
is.character(x) && length(x) == 1L && !is.na(x)
}
Then:
if (missing(param1) || !isSingleString(param1)) {
stop("param1 must be a single, non-NA string")
}
To ensure not to have problms with misisng parameters, you should provide default arguments.
Use stopifnot, it is designed to check arguments.
here how I would do this:
func_check <-
function(param1="",param2=""){
stopifnot(typeof(param1) == "character",
typeof(param2) == "character")
}
## param2 is numeric
func_check(param1= 'a',param2=2)
## param2 is missing
func_check(param1= 1)
EDIT
In case you want to check for missing values , toy shoudl use dotted parameters. Then you can deal it with using the match.call. Here an example where I test for missings and not valid parameters.
func_check <-
function(...){
ll <- as.list((match.call()[-1]))
stopifnot(c('param1','param2' )%in% names(ll))
param1 = ll$param1
param2 = ll$param2
stopifnot(typeof(param1) == "character",
typeof(param2) == "character")
}
func_check(param1= 'a',param2=2)
If I define the following function:
myfunc <- function(param1, param2, numeric1, param3) {
if (!is.character(param1) || !is.character(param2)) {
stop("You must provide valid arguments for param1 and param2")
} else if(!is.numeric(numeric1)) {
stop("Please provide numeric input")
} else if(!is.character(param3)){
stop("Please provide character input for param3")
}
#some code here for your function, e.g.
paste0(param1, param2, numeric1, param3)
}
It throws an error whenever I don't give it 4 input parameters in the call of myfunc, including if I call it without any arguments (so the error occurs both if aguments are missing and when they are not of the correct type). Is that different from what you are looking for?
Suppose I have a function
test <- function(s,t) {
..
}
that requires two arguments.
How can I make it so that it also takes one single argument, i.e. test(t) would return test(t,t)? Thanks in advance.
Because R uses lazy evaluation you can set the default value of the second argument equal to the first argument ...
foo <- function(s,t=s) {
s+t
}
> foo(4)
[1] 8
> foo(4,5)
[1] 9
Setting a default value for an argument is the simplest, but you can also use the missing function inside of the function (in an if statement) to check if an argument was supplied to the function and do something different based on that.