non-numeric argument to binary operator when defining a data.frame method for `+` and using on ggplot object

房东的猫 提交于 2021-01-28 01:03:58

问题


I can define a S3 method like this :

`+.data.frame` <- function(e1,e2){"hello"}
iris + iris
# [1] "hello"

But this won't work if e2 is a gg object :

iris + geom_point()

Error in iris + geom_point() : non-numeric argument to binary operator

In addition: Warning message: Incompatible methods ("+.data.frame", "+.gg") for "+"

I think it has something to do with S4 methods but I'm confused. Can you explain what's at play and how to sort it out ?

desired output :

iris + geom_point()
# [1] "hello"

回答1:


This is actually not due to S4 methods but a method conflict. Neither geom_point() nor your data frame are S4 objects (isS4 on either of them returns FALSE), so S4 methods will not come into play.

The ggplot package defines a method for + on gg-classed objects, and you have just defined a method for data.frames. The trouble is, unlike most S3 generic functions, + takes the class of both arguments into account in selecting a method. In this case, it concludes that it could have legitimately chosen the gg method as well as the data.table method.

From the help page for "Ops" (of which "+" is a member):

The classes of both arguments are considered in dispatching any member of this group. For each argument its vector of classes is examined to see if there is a matching specific (preferred) or Ops method. If a method is found for just one argument or the same method is found for both, it is used. If different methods are found, there is a warning about ‘incompatible methods’: in that case or if no method is found for either argument the internal method is used.

So you see in this case, it falls through to the default + code, which doesn't know how to add data frames and gg objects, and returns an error saying as much.

To solve the issue, you may be able to write an S4 method with signature (data.frame,gg) (or perhaps (data.frame,ANY) but beware — it will only actually be called if one of the arguments is an S4 object (which data.frames are not by default). You may have to define your own class which contains data.frame (or, alternatively, contains gg) in order to trigger the method.



来源:https://stackoverflow.com/questions/55019663/non-numeric-argument-to-binary-operator-when-defining-a-data-frame-method-for

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!