What is the explanation for the following behavior?
is.list(data.frame()) ## TRUE
is(data.frame(),'list') ## FALSE
is(data.frame()) ## "data.frame" "list" "oldClass" "vector"
extends('data.frame','list') ## TRUE
inherits(data.frame(),'list') ## FALSE
You are mixing S3 and S4 class conventions. is
and extends
are for S4 classes but these work with S3 ones because of the way these have been implemented. inherits
was written for S3 classes and it is not intended to work with S4 objects with full compatibility.
inherits
effectively compares the result of class(x)
with the class you specify in the second argument. Hence
> class(data.frame())
[1] "data.frame"
doesn't contain "list"
anywhere so fails.
Note also this from ?inherits
:
The analogue of ‘inherits’ for formal classes is ‘is’. The two
functions behave consistently with one exception: S4 classes can
have conditional inheritance, with an explicit test. In this
case, ‘is’ will test the condition, but ‘inherits’ ignores all
conditional superclasses.
Another confusion is with the class of an object and the implementation of that object. Yes a data frame is a list as is.list()
tells us, but in R's S3 class world, data.frame()
is of class "data.frame"
not "list"
.
As for is(data.frame(),'list')
, well it isn't of that specific class "list"
hence the FALSE
. What is(data.frame())
does is documented in ?is
Summary of Functions:
‘is’: With two arguments, tests whether ‘object’ can be treated as
from ‘class2’.
With one argument, returns all the super-classes of this
object's class
Hence is(data.frame())
is showing the classes that the "data.frame"
class extends (in the S4 sense, not the S3 sense). This further explains the extends('data.frame','list')
behaviour as in the S4 world, the "data.frame"
class does extend the "list"
class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With