Reputation: 348
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
Reputation: 153852
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
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
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