Rainer pointed out, in response to my post, Row names in data frames: Beware of 1:nrow, that if I’d used rownames(x) <- as.character(1:3)
rather than rownames(x) <- 1:3
, I wouldn’t have had the problem I’d seen.
> x <- z <- data.frame(id=1:3)
> y <- data.frame(id=4:6)
> rownames(x) <- 1:3
> rownames(y) <- LETTERS[4:6]
> rownames(z) <- as.character(1:3)
> rbind(y,x)
id
D 1
E 2
F 3
4 1
5 2
6 3
> rbind(y,z)
id
D 1
E 2
F 3
1 1
2 2
3 3
If you type rownames(x)
you see the same result as rownames(z)
, and is.character(rownames(x))
and is.character(rownames(z))
both return TRUE, but if you look at the "row.names"
attribute directly, you see they are different.
> rownames(x)
[1] "1" "2" "3"
> rownames(z)
[1] "1" "2" "3"
> is.character(rownames(x))
[1] TRUE
> is.character(rownames(z))
[1] TRUE
> attr(x, "row.names")
[1] 1 2 3
> attr(z, "row.names")
[1] "1" "2" "3"
But why is 1:3
treated so differently from 2:4
?
> w <- data.frame(id=1:3)
> rownames(w) <- 2:4
> attr(w, "row.names")
[1] 2 3 4
> rownames(rbind(y,w))
[1] "D" "E" "F" "2" "3" "4"