Bug 14469 - mostattributes<- removes names attributes from data.frames
mostattributes<- removes names attributes from data.frames
Status: CLOSED INVALID
Product: R
Classification: Unclassified
Component: Language
R 2.12.0
All Linux
: P5 minor
Assigned To: R-core
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-01-01 14:43 UTC by DAV
Modified: 2011-01-13 09:46 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description DAV 2011-01-01 14:43:53 UTC
mostattributes<- is removing the "names" attribute of data.frames. The relevant lines of code are below. A data.frame returns a non-null dim value thus the guard for setting names fails on data.frames. 

		if (h.nam <- !is.na(inam <- match("names", names(value)))) {
			n1 <- value[[inam]]
			value <- value[-inam]
		}
       ...
		attributes(obj) <- value  ## <<<--- REMOVES names
		dm <- dim(obj)            ## <<<- data.frames return non-NULL!!
		L <- length(if (is.list(obj)) unclass(obj) else obj)
		if (h.nam && is.null(dm) && L == length(n1))  ## <<<-- FAILS !!
			names(obj) <- n1

My fix may not be elegant but adding the following after the last statement seems to work:

		if (h.nam && is.data.frame(obj) && L == length(n1)) 
			names(obj) <- n1
Comment 1 Brian Ripley 2011-01-12 18:36:09 UTC
There is no example here, and I do not read the documentation to say that
names will be set for data frames (rather than they will not be set when
not appropriate).

It might be better to look at the 'dim' attribute rather than call dim(),
but we do need an example of what this is trying to solve.
Comment 2 DAV 2011-01-12 21:28:55 UTC
The bug is that the names attributes for data.frames are REMOVED regardless of the input attribute list. This causes the column names to be lost.

Example:

> df = data.frame(x=rep(1,3),y=rep(2,3))
> dfx = df          ## make another df we are going to change
> attributes(df)
$names
[1] "x" "y"

$row.names
[1] 1 2 3

$class
[1] "data.frame"

> attr(df,'time') = Sys.time()
> attributes(df)     ## <<<<<<<<<<<<<<<< Set an extra attribute
$names               ## <<<<<<<<<<<<<<<< names are still here
[1] "x" "y"

$row.names
[1] 1 2 3

$class
[1] "data.frame"

$time
[1] "2011-01-12 15:20:15 EST"

> mostattributes(dfx)=attributes(df)
> attributes(dfx)      ## <<<<<<<<<<<<<<< Note that 'names' has been removed
$row.names
[1] 1 2 3

$class
[1] "data.frame"

$time
[1] "2011-01-12 15:20:15 EST"
Comment 3 Brian Ripley 2011-01-13 09:46:13 UTC
mostattributes<- always removes any existing attributes, as documented.
So removing names cannot be a bug.

Nevertheless, using the 'dim' attribute would make it more flexible, and will be changed in future.