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")
}
Related
I want to use quoted arguments in my function and I would like to allow the user to specify that they don't want to use the argument by setting it to NULL. However, rlang::ensym throws an error when it receives a NULL argument. Here is my code:
f <- function(var){
rlang::ensym(var)
return(var + 2)
}
# This works
variable = 2
f(variable)
# This throws an error
f(NULL)
The error message is:
Error: Only strings can be converted to symbols
I already tried adding an if-clause with is.null(var) before the expression with rlang::ensym, but of course, this doesn't work as the variable is not yet quoted at this time.
How can I check that the supplied quoted variable is NULL in order to handle it differently?
If you need to allow for NULL, it's more robust to use quosures first. Then you can inspect the quosure to see what's inside. For example
f <- function(var){
var <- rlang::enquo(var)
if (rlang::quo_is_null(var)) {
var <- NULL
} else if (rlang::quo_is_symbol(var)) {
var <- rlang::get_expr(var)
} else {
stop(paste("Expected symbol but found", class(rlang::get_expr(var))))
}
return(var)
}
And that returns
f(variable)
# variable
f(NULL)
# NULL
f(x+1)
# Error in f(x + 1) : Expected symbol but found call
Or you can use whatever logic is appropriate for your actual requirements.
Write a function named countConsecutivePairs that accepts a numeric vector as an argument and counts the pairs of consecutive elements whose difference is less than 2.
You should stop the execution and print an appropriate error message if the argument is not numeric.
Here is my code
countConsecutivepairs=function(z){
if(!(is.vector(z)))
stop("Error"
if(class(z)!="numeric")
stop("Error")
for(i in z) {
if(abs(z[i]-z[i+1])!=2){
next
}
print(c(z[i],z[i+1])
}
}
I get a bunch of errors when I do this. And Im not sure how to fix it.
You miss several ) in your code.
And thanks to #Jan, as #Ace123 use z[i]'s in code and also want to check consecutive elements, we should call those elements by i against length of z.
countConsecutivepairs<- function(z){
if(!(is.vector(z))){
stop("Error")
}
if(class(z)!="numeric"){
stop("Error")
}
for(i in 1:(length(z)-1)) {
if(abs(z[i]-z[i+1])!=2){
next
}
print(c(z[i],z[i+1]))
}
}
countConsecutivepairs(c(1,2,3,5,7))
[1] 3 5
[1] 5 7
I am building a function in R that calculates the pythagorean of a triangle. The function can take 3 arguments: a,b,c. However, it requires that only 2 of them be inputted, or it throws an error, since a Pythagorean can only be calculated with 2 sides. How do I make a function that 3 inputs but only requires 2?
You can assign default values to arguments within your argument list to prevent the error. In this case, assign NULL to all.
pythag <- function(a=NULL, b=NULL, c=NULL) {
if(length(c(a, b, c))!=2)
stop("You must supply exactly 2 of a, b and c")
...
}
If you wanted to add other checks, such as numeric values, you can do these individually:
if(is.null(a) && is.numeric(b) && is.numeric(c))
return(sqrt(c^2 - b^2))
else if(is.null(b) && is.numeric(a) && is.numeric(c))
return(sqrt(c^2 - a^2))
else if(is.null(c) && is.numeric(a) && is.numeric(b))
return(sqrt(a^2 + b^2))
print("All arguments must be numeric")
}
I made a function to to compute the sum of I(Xi
my.ecdf<- function(x,y) {
if(!is.null(dim(y)))
stop("y has more than one dimension")
n<-length(x)
i<-1:n
p<-if(x[i]<y) 1 else {
0
}
(sum(p))/n
}
But when I run it with input (rnorm(11),6), I get this error:
Warning message:
In if (x[i] < y) 1 else { :
the condition has length > 1 and only the first element will be used
Any ideas? I'm new to r so sorry if it's something obvious. (Also I don't want to use the for loop)
There are a number of issues in your code:
1) Whats the point of x[1:length(x)] in the if statement? Right now these are meaningless and can be dropped:
n<-length(x)
i<-1:n
x[i]
2) If statement accepts a logical argument not a vector of logical, you can consider adding all() any() etc like
if(all(x < y)) 1 else {0}
or use ifelse() statement for the assignment
3) Finally from what I can understand you overcomplicate things and the whole thing can be written as one-liner:
sum(x < y)/length(x)
This is a logical vector of the same length as y
is.null(dim(y))
You're using it as a logical test. An object with a length greater than 1 can't be unambiguously interpreted by the if statement. Consider if (TRUE FALSE FALSE TRUE) <do something>. When should you do that thing?
If you want to make sure y doesn't have more than one dimension, do
if(length(dim(y)) > 1){
stop("message")
}
Background
I have a simple function called TBT. This function has a single argument called x. A user can provide any type rdistribution_name() (e.g., rnorm(), rf(), rt(), rbinom() etc.) existing in R for argument x, EXCEPT ONE: "rcauchy()".
Question
I was wondering how R could recognize that a user has provided an rcauchy() as the input for x, and when this is the case, then R issues a warning message?
Here is my R code with no success:
TBT = function(x) {
if( x == rcauchy(...) ) { warning("\n\tThis type of distribution is not supported.") }
}
TBT( x = rcauchy(1e4) )
Error in TBT(rcauchy(10000)) : '...' used in an incorrect context
If you are expeciting them do call to random function when they call your function, you could so
TBT <- function(x) {
xcall <- match.call()$x
if (class(xcall)=="call" && xcall[[1]]=="rcauchy") {
warning("\n\tThis type of distribution is not supported.")
}
}
TBT( x = rcauchy(1e4) )
But this would not catch cases like
x <- rcauchy(1e4)
TBT( x )
R can't track where the data in the x variable came from