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’."