I received the error
Error in if (condition) { : argument is of length zero
or
Error in while (condition) { : argument is of length zero
What causes this error message, and what does it mean?
On further inspection it seems that the value is NULL.
condition
## NULL
In order to deal with this error, how do I test for NULL values?
I expected that this would return TRUE, but I got an empty logical value:
condition == NULL
## logical(0)
See ?NULL
You have to use is.null
‘is.null’ returns ‘TRUE’ if its argument is ‘NULL’ and ‘FALSE’
otherwise.
Try this:
if ( is.null(hic.data[[z]]) ) { print("is null")}
From section 2.1.6 of the R Language Definition
There is a special object called NULL. It is used whenever there is a need to indicate or
specify that an object is absent. It should not be confused with a vector or list of zero
length.
The NULL object has no type and no modifiable properties. There is only one NULL object
in R, to which all instances refer. To test for NULL use is.null. You cannot set attributes
on NULL.
What causes this error message, and what does it mean?
if statements take a single logical value (technically a logical vector of length one) as an input for the condition.
The error is thrown when the input condition is of length zero. You can reproduce it with, for example:
if (logical()) {}
## Error: argument is of length zero
if (NULL) {}
## Error: argument is of length zero
Common mistakes that lead to this error
It is easy to accidentally cause this error when using $ indexing. For example:
l <- list(a = TRUE, b = FALSE, c = NA)
if(l$d) {}
## Error in if (l$d) { : argument is of length zero
Also using if-else when you meant ifelse, or overriding T and F.
Note these related errors and warnings for other bad conditions:
Error in if/while (condition) {: missing Value where TRUE/FALSE needed
Error in if/while (condition) : argument is not interpretable as logical
if (NA) {}
## Error: missing value where TRUE/FALSE needed
if ("not logical") {}
## Error: argument is not interpretable as logical
if (c(TRUE, FALSE)) {}
## Warning message:
## the condition has length > 1 and only the first element will be used
How do I test for such values?
NULL values can be tested for using is.null. See GSee's answer for more detail.
To make your calls to if safe, a good code pattern is:
if(!is.null(condition) &&
length(condition) == 1 &&
!is.na(condition) &&
condition) {
# do something
}
You may also want to look at assert_is_if_condition from assertive.code.
When testing for NULL values, you want to use is.null(hic.data[[z]]).
Related
I have a vector arguments, where some values are NA. I would like to pass these arguments sequentially to a function like this:
myFunction(argument = ifelse(!is.na(arguments[i]),
arguments[i], NULL))
so that it will take the value in arguments[i] whenever it's not NA, and take the default NULL otherwise. But this generates an error.
If it makes any difference, the function in question is match_on(), from the optmatch package. The argument in question is caliper, because I would like to provide a caliper only when one is available (i.e. when the value in the vector of calipers is not NA). And the error message is this:
Error in ans[!test & ok] <- rep(no, length.out = length(ans))[!test & :
replacement has length zero
In addition: Warning message:
In rep(no, length.out = length(ans)) :'x' is NULL so the result will be NULL
You can use ?switch() instead of ifelse -
myFunction(argument = switch(is.na(arguments[i]) + 1, arguments[i], NULL))
Here's the help doc for switch -
switch(EXPR, ...)
Arguments
EXPR an expression evaluating to a number or a character string.
... the list of alternatives. If it is intended that EXPR has a
character-string value these will be named, perhaps except for one
alternative to be used as a ‘default’ value.
Details
switch works in two distinct ways depending whether the first argument
evaluates to a character string or a number.
If the value of EXPR is not a character string it is coerced to
integer. If the integer is between 1 and nargs()-1 then the
corresponding element of ... is evaluated and the result returned:
thus if the first argument is 3 then the fourth argument is evaluated
and returned
Basically, when argument is NA then EXPR evaluates to 2 which returns NULL and when it is not NA then EXPR evaluates to 1 and returns arguments[i].
Having trouble setting up these integral terms in R. I created "term1" to more easily insert it into the integral code, but I keep getting various error messages after trying different codes. any help or spotting the issue would be appreciated.
##
S<-readline(prompt="Enter underlying instrument price:")
X<-readline(prompt="Enter strike price:")
V<-readline(prompt="Enter absolute volatility in dollars:")
r<-readline(prompt="Enter risk-free rate (%):")
q<-readline(prompt="Enter dividend yield (%):")
T<-readline(prompt="Enter time to maturity, in fraction of years:")
t=0
##
S<-as.numeric(S)
X<-as.numeric(X)
V<-as.numeric(V)
r<-as.numeric(r)/100
q<-as.numeric(q)/100
T<-as.numeric(T)
##Bond Price
B<-exp(r*(T-t))
##Volatility
vol<-function(start,end,rate,yield,B) {
if(r==q){
V*(sqrt((B-1)/(2*(r-q))))
}
else{
V*(sqrt(T-t))
}
}
##d
d<-(S*B-X)/vol()
##N(d)
term1<-(exp(-(r^2)/2)/sqrt(2*pi))
#Call
Nc<-function(term1){
Nc<-((integrate(term1,-Inf,d)))}
#Put
Np<-function(term1){
Np<-(-(integrate(term1,-Inf,d)))}
These are the errors i am getting
> Nc(term1)
Error in get(as.character(FUN), mode = "function", envir = envir) :
object 'term1' of mode 'function' was not found
> Nc()
Error in match.fun(f) : argument "term1" is missing, with no default
Well, the big question is: Have you read the documentation for function integrate ?
The first argument you assign to that function has to be a function.
The second problem is, that function Nc, which you have defined, does not return any output (you can fix that by not assigning the result of integrate to an object and instead just returning it. Same goes for the Np. One more problem with Np is, that it actually returns an error "unexpected argument to unary operator"
Anyway, here is the code with some changes:
## Assign some "random" numbers to the variables, so that I can run the script
S<-100
X<-110
V<-3
r<-10
q<-15
# Is it a good idea to have variable called T? T stands also for TRUE
T <- 10
t=0
##
S<-as.numeric(S)
X<-as.numeric(X)
V<-as.numeric(V)
r<-as.numeric(r)/100
q<-as.numeric(q)/100
T<-as.numeric(T)
##Bond Price
B<-exp(r*(T-t))
##Volatility
vol<-function(start,end,rate,yield,B) {
if(r==q){
V*(sqrt((B-1)/(2*(r-q))))
}
else{
V*(sqrt(T-t))
}
}
##d
d<-(S*B-X)/vol()
# make term1 a function of r, so that there is actually something to integrate...
term1<-function(r) {(exp(-(r^2)/2)/sqrt(2*pi))}
# Do not assign the result of integration to an object, otherwise there will be no output from the function
Nc<-function(term1){
((integrate(term1,-Inf,d)))}
# In order to use the minus sign, you have to extract the value from the result of function "integrate"
Np<-function(term1){
(-(integrate(term1,-Inf,d)$value))}
I am really new to R. Allow me to ask a beginner's question.
When I type p.adjust, for example, I can see the following. It seems that the argument method is p.adjust.methods by default. I tried to trace the code but when I typed something like:
match.arg(p.adjust.methods)
It says:
Error in match.arg(p.adjust.methods) : 'arg' must be of length 1
Why?
> p.adjust
function (p, method = p.adjust.methods, n = length(p))
{
method <- match.arg(method)
...
}
The match.arg function does not work in interactive mode in its one argument form, since there is nothing to match to. That first argument is expected to be a length 1 character vector, and it is tested against the known methods _inside_the_function_:
> ?p.adjust
> p.adjust.methods
[1] "holm" "hochberg" "hommel" "bonferroni" "BH" "BY" "fdr"
[8] "none"
(The first argument to p.adjust if you are using positional matching needs to be a vector of p-values.)
Can someone tell me what is wrong with this if-else loop in R? I frequently can't get if-else loops to work. I get an error:
if(match('SubjResponse',names(data))==NA) {
observed <- data$SubjResponse1
}
else {
observed <- data$SubjResponse
}
Note that data is a data frame.
The error is
Error in if (match("SubjResponse", names(data)) == NA) { :
missing value where TRUE/FALSE needed
This is not a full example as we do not have the data but I see these issues:
You cannot test for NA with ==, you need is.na()
Similarly, the output of match() and friends is usually tested for NULL or length()==0
I tend to write } else { on one line.
As #DirkEddelbuettel noted, you can't test NA that way. But you can make match not return NA:
By using nomatch=0 and reversing the if clause (since 0 is treated as FALSE), the code can be simplified. Furthermore, another useful coding idiom is to assign the result of the if clause, that way you won't mistype the variable name in one of the branches...
So I'd write it like this:
observed <- if(match('SubjResponse',names(data), nomatch=0)) {
data$SubjResponse # match found
} else {
data$SubjResponse1 # no match found
}
By the way if you "frequently" have problems with if-else, you should be aware of two things:
The object to test must not contain NA or NaN, or be a string (mode character) or some other type that can't be coerced into a logical value. Numeric is OK: 0 is FALSE anything else (but NA/NaN) is TRUE.
The length of the object should be exactly 1 (a scalar value). It can be longer, but then you get a warning. If it is shorter, you get an error.
Examples:
len3 <- 1:3
if(len3) 'foo' # WARNING: the condition has length > 1 and only the first element will be used
len0 <- numeric(0)
if(len0) 'foo' # ERROR: argument is of length zero
badVec1 <- NA
if(badVec1) 'foo' # ERROR: missing value where TRUE/FALSE needed
badVec2 <- 'Hello'
if(badVec2) 'foo' # ERROR: argument is not interpretable as logical
What is the difference between NULL and character(0) | integer(0) etc?
> identical(NULL, character(0))
[1] FALSE
> is.null(integer(0))
[1] FALSE
> str(character(0))
chr(0)
> str(NULL)
NULL
In general it seems you can pass NULL as parameters into functions, and that an empty vector is generally returned as character(0), integer(0), etc.
Why is this the case? Come to think of it, is there a test for zero-ness, a la is.integer0?
The R Language Definition has this on NULL:
There is a special object called NULL. It is used whenever there is a need to indicate or
specify that an object is absent. It should not be confused with a vector or list of zero
length. The NULL object has no type and no modifiable properties. There is only one NULL
object in R, to which all instances refer. To test for NULL use is.null. You cannot set
attributes on NULL.
So by definition NULL is very different to zero length vectors. A zero length vector very much isn't absent. NULL is really a catch-all for something that is absent or not set, but not missing-ness, which is the job of NA. There is an exception, the zero-length pairlist, as mentioned by #Owen. The Language Definition states:
A zero-length pairlist is NULL, as would be expected in Lisp but in contrast to a zero-length list.
which highlights the exception in this case.
To test for a zero-length vector use something like if(length(foo) == 0L) for example. And combine that with a class check (is.character(foo)) if you want a specific type of zero length vector.
The other guys have the right answers, but I want to add a few curiosities.
First, it's not quite true that NULL "is used whenever there is a need to indicate or specify that an object is absent" as it says in the doc. There are actually 2 other "no data" values in R (not counting NA, which is not a complete value).
There's "missing", which is used for missing arguments:
alist(x=)$x
> identical(NULL, alist(x=)$x)
[1] FALSE
> y = alist(x=)$x
> y
Error: argument "y" is missing, with no default
Then there's "unbound", which you can't (AFAIK) access directly, but using C:
SEXP getUnbound(void) {
return R_UnboundValue;
}
> x = .Call("getUnbound")
> x
Error: object 'x' not found
Here's a partial answer, beginning by simply quoting the R Language Definition Guide:
There is a special object called NULL. It is used whenever there is a
need to indicate or specify that an object is absent. It should not be
confused with a vector or list of zero length. The NULL object has no
type and no modifiable properties. There is only one NULL object in R,
to which all instances refer. To test for NULL use is.null. You cannot
set attributes on NULL.
I take that to mean that zero length vectors can have attributes, whereas NULL cannot:
> x <- character(0)
> y <- NULL
> attr(x,"name") <- "nm"
> attr(y,"name") <- "nm"
Error in attr(y, "name") <- "nm" : attempt to set an attribute on NULL