1
votes

I have a data frame T that is a mixture of numeric and string:

 T1<-c(1,2, 3,4,6)
 T2<-c(4,5, 5,7,8)
 T3<-c("a","b","c","d","e")
 T4<-c(4,5, 5,7,8)
 T5<-c(4,5, 5,7,8)
 T<-data.frame(T1,T2,T3,T4,T5)

When I apply function to the numeric value of each row using follwong code:

  P=apply(T,1,FUN=function(x) ifelse(x[1]>=x[4]+2*x[5],1,0))

It always give error message "Error in 2 * x[5] : non-numeric argument to binary operator". But if I replace T3 with all numeric values, it works perfectly.

I am puzzled by this and wondering anyone has any insight?

thanks!

1
You are using apply to a data.frame. apply is meant for array objects and so it converts T to a matrix. Since your data.frame contains character column, it will be coerced to a character matrix and so arithmetic operations are not allowed.nicola
@D Jay You could have just used (T[,1]>=T[,4]+2*T[,5])+0akrun
Thanks for your explanation, that made the point!D Jay

1 Answers

4
votes

You get coercion of each row to character because T3 is included in what is passed from your dataframe to the function by apply. You could fix this with:

P=apply(T[-3],1,FUN=function(x) ifelse(x[1]>=x[3]+2*x[4],1,0))

The error is not from the comparison but rather from the attempt to multiply a character value by a numeric. It also might have succeeded with:

P=apply(T,1,FUN=function(x) ifelse(as.numeric(x[1])>= as.numeric(x[4])+ 
                                                  2*as.numeric(x[5])
                                   ,1,0))

But this is "just wrong". The use of apply is appropriate for matrices where all modes of the columns are the same, but it is generally slower than vectorized functions like ifelse which offer row-wise processing without resorting to apply. Should be:

P=with(T,  ifelse(T1 >= T4 +  2*T5, 1,0) )

Or just use Boolean arithmetic and convert back to numeric 0/1:

P=  with(T, as.numeric( T1 >= T4 +  2*T5 ) ) # @akrun gets the check