Unlike attr it is not an error to set attributes on a
  NULL object: it will first be coerced to an empty list.
Note that some attributes (namely class,
  comment, dim, dimnames,
  names, row.names and
  tsp) are treated specially and have restrictions on
  the values which can be set.  (Note that this is not true of
  levels which should be set for factors via the
  levels replacement function.)
Attributes are not stored internally as a list and should be thought
  of as a set and not a vector, i.e, the order of the elements of
  attributes() does not matter.  This is also reflected by
  identical()'s behaviour with the default argument
  attrib.as.set = TRUE.  Attributes must have unique names (and
  NA is taken as "NA", not a missing value).
Assigning attributes first removes all attributes, then sets any
  dim attribute and then the remaining attributes in the order
  given: this ensures that setting a dim attribute always precedes
  the dimnames attribute.
The mostattributes assignment takes special care for the
  dim, names and dimnames
  attributes, and assigns them only when known to be valid whereas an
  attributes assignment would give an error if any are not.  It
  is principally intended for arrays, and should be used with care on
  classed objects.  For example, it does not check that
  row.names are assigned correctly for data frames.
The names of a pairlist are not stored as attributes, but are reported
  as if they were (and can be set by the replacement form of
  attributes).
NULL objects cannot have attributes and attempts to
  assign them will promote the object to an empty list.
Both assignment and replacement forms of attributes are
  primitive functions.