The R language definition (for version 3.5.1) states
The expression
x[]
returnsx
, but drops “irrelevant” attributes from the result. Onlynames
and in multi-dimensional arraysdim
anddimnames
attributes are retained.
But consider the following example:
v <- factor(c(dog = 1, cat = 3))
attr(v, "label") <- "feeling confused"
attributes(v)
# $`names`
# [1] "dog" "cat"
#
# $levels
# [1] "1" "3"
#
# $class
# [1] "factor"
#
# $label
# [1] "feeling confused"
attributes(v[])
# $`names`
# [1] "dog" "cat"
#
# $levels
# [1] "1" "3"
#
# $label
# [1] "feeling confused"
#
# $class
# [1] "factor"
Attribute order is changed but all the attributes are retained.
all.equal(attributes(v)[c(1,2,4,3)], attributes(v[]))
# [1] TRUE
Why is my example exempt? Or what am I missing?
I think it may simply be mis-documented in the current R language definition document.
As you've found, the behaviour is opposite to what is described. Note that, in your example, if you subset using v[1:length(v)]
, you get the behaviour you expected from v[]
. So the empty []
is the exception that returns the attributes unchanged.
Looking for the answer I found an illustrative commit/comment (see diffs here: https://github.com/wch/r-source/commit/6b3480e05e9671a517d70c80b9f3aac53b6afd9d#diff-3347e77b1c102d875a744a2cd7fa86e5) The author describes the behaviour that you have observed:
Subsetting (other than by an empty index) generally drops all attributes except @code{names}, @code{dim} and @code{dimnames} which are reset as appropriate. On the other hand, subassignment generally preserves attributes even if the length is changed. Coercion drops all attributes.
I think if the subset []
is empty, the object that is returned is simply a copy of the original object.
EDIT (from comments below):
The reason that the attributes of v
and v[]
appear in a different order, is likely because of the way the attributes are assigned to the new subset in this special case of subsetting with an empty index. Further, the different order shouldn't be considered a bug, because attributes are not supposed to have an order (see help(attributes)
. Note that in help(``[``)
, the behaviour you observed is accurately described (unlike in language definition you referenced), and explains why one would want this behaviour:
An empty index selects all values: this is most often used to replace all > the entries but keep the ‘attributes’."
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