showkey
showkey

Reputation: 348

"argument is of length zero" in if statement

I want to compute my data according to rule that number+W is number*2.

dat="1W   16   2W   16
      1   16   2W    0
     1W   16   16    0
      4   64   64    0"     
data=read.table(text=dat,header=F)
apply(data,c(1,2),function(y){
     if(grep(pattern="W",y) ==1 )
     {  gsub("W",paste("*",2,sep=""),y)->s;
         eval(parse(text=s));
      } else 
        {y <- y }
      })

But I get the output:

Error in if (grep(pattern = "W", y) == 1) { : argument is of length zero

Why? If y matches "W" then the value is 1, what is wrong with my code?

Upvotes: 2

Views: 17770

Answers (3)

Eric Leschinski
Eric Leschinski

Reputation: 153852

R 3.4.1 Error: "argument is of length zero" in if statement

If you pass an empty vector into an if statement such as:

myvariable = c()
if (myvariable){ 
    print("hello") 
} 

You will get an error:

Error in if (myvariable) { : argument is of length zero

Empty R vectors can bubble up data-type errors through functions like grep, for example:

if (grepl("foo", c(), fixed = TRUE)){ 
    print("yes") 
} 

Which fails:

Error in if (grepl("foo", c(), fixed = TRUE)) { : 
  argument is of length zero

So the remedy is to do more type checking of your variables before feeding them as arguments to either if statements, or functions like grep.

Upvotes: 0

Carl Witthoft
Carl Witthoft

Reputation: 21492

Here's a rather bizarre approach, which does work just fine:

library(sfsmisc)

foo<- c('2','23', 'W4','W53','17')
bar<-sapply(foo, function(x)AsciiToInt(x))
barw<-sapply(bar,function(x)x[x!=87])
bard<-logical(length(foo))
for (i in 1:length(foo) ) bard[i]<-length(barw[[i]])== length(bar[[i]])

foow<-vector()
for(i in 1:length(foo)) foow[i]<-as.numeric(paste0(chars8bit(barw[[i]]),collapse='') ) *(1+!bard[i])

Upvotes: 0

Simon O&#39;Hanlon
Simon O&#39;Hanlon

Reputation: 59970

Your query can be illustrated with the following example:

grep(pattern="W","huh")
# integer(0)

No match results in a vector of length 0, hence the error. Instead use grepl, i.e. if( grepl( "W" , y ) ).

grepl has the return value TRUE or FALSE.

As a side note, eval( parse( "sometext" ) ) is variously thought of as not a good idea. You could try using the following untidy lapply statement instead (which will be better than apply because you don't have to convert to a matrix first):

data.frame( lapply( data , function(x) 
                                ifelse( grepl("W",x) , 
                                        as.integer( gsub("W","",x) ) * 2L , 
                                        x ) ) )
#  V1 V2 V3 V4
#1  2 16  4 16
#2  1 16  4  0
#3  2 16  1  0
#4  3 64  3  0

Upvotes: 8

Related Questions