二元运算符的非数字参数(non-numeric argument to binary operator)

我有一个数据框T,它是数字和字符串的混合:

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)

当我使用follwong代码将函数应用于每行的数值时:

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

它始终给出错误消息“2 * x [5]中的错误:二元运算符的非数字参数”。 但是,如果我用所有数值替换T3,它可以完美地工作。

我很困惑,想知道任何人有任何见解?

谢谢!

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!

最满意答案

您将每行强制转换为字符,因为T3包含在通过apply从数据帧传递给函数的内容中。 你可以解决这个问题:

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

错误不是来自比较,而是来自尝试将字符值乘以数字。 它也可能成功:

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

但这是“错误的”。 apply的使用apply于列的所有模式相同的矩阵,但它通常比像ifelse这样的矢量化函数更慢, ifelse提供逐行处理而无需ifelse 。 应该:

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

或者只使用布尔算术并转换回数字0/1:

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

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

更多推荐