R中的行名和列名

53
这些函数对是否生成完全相同的结果有疑问:
1. names()colnames() 2. rownames()row.names()

1
为什么不运行它们并找出答案呢? - EJoshuaS - Stand with Ukraine
4个回答

81

正如奥斯卡·王尔德所说:

一致性是缺乏想象力者的最后避难所。

R更像是一种进化而非设计出来的语言,所以这种情况会发生。 names()colnames() 可以用于 data.frame,但是 names() 不能用于矩阵:

R> DF <- data.frame(foo=1:3, bar=LETTERS[1:3])
R> names(DF)
[1] "foo" "bar"
R> colnames(DF)
[1] "foo" "bar"
R> M <- matrix(1:9, ncol=3, dimnames=list(1:3, c("alpha","beta","gamma")))
R> names(M)
NULL
R> colnames(M)
[1] "alpha" "beta"  "gamma"
R> 

2
数据类型之间存在差异。 - Jay
7
爱默生曾说过:“愚蠢的一贯性是小心灵的妖怪,被小政治家、哲学家和神职人员所崇拜。对于伟大的灵魂来说,一贯性根本无足轻重。” - Ken Williams
5
拉里·沃尔(Larry Wall)说:“我知道这很奇怪,但它确实使写诗更容易。” http://groups.google.com/group/comp.lang.perl/msg/5b26830b9e52189e - JD Long
1
colnames可以在矩阵上正常工作,手册中已明确说明。 - Tomas
2
@DirkEddelbuettel 好程序员笑话!:-)) 但是你没有纠正它的事实让我担心你并不是在开玩笑?我猜我们都知道在人类语言中这个理解是不同的,因为“names()适用于....和colnames()适用于....”。 - Tomas
显示剩余7条评论

8

稍微解释一下Dirk的例子:

可以将数据框想象为长度相等的向量列表。这可能是为什么names函数适用于数据框而不适用于矩阵的原因。

另一个有用的函数是dimnames,它返回每个维度的名称。你会注意到rownames函数实际上只是从dimnames返回第一个元素。

关于rownamesrow.names:我无法区分它们之间的差异,尽管rownames使用了dimnames,而row.names是在R之外编写的。它们似乎也能够处理更高维数组:

>a <- array(1:5, 1:4)
> a[1,,,]
> rownames(a) <- "a"
> row.names(a)
[1] "a"
> a
, , 1, 1    
  [,1] [,2]
a    1    2

> dimnames(a)
[[1]]
[1] "a"

[[2]]
NULL

[[3]]
NULL

[[4]]
NULL

1
这是一个更好的答案。讽刺是有趣的,但知识更实用。data.frame确实可用作列的列表和矩阵,即每一列具有相同的长度,您可以提取单个行或行的子集。 - flying sheep

5

我认为使用colnamesrownames是最合理的选择,以下是原因。

使用names有几个缺点。首先,你必须记住它表示“列名”,并且它只适用于数据框,所以你需要每次在使用矩阵时调用colnames。而通过调用colnames,你只需要记住一个函数。最后,如果你查看colnames的代码,你会发现在数据框的情况下它仍然调用names,因此输出是相同的。

rownamesrow.names对于数据框和矩阵返回相同的值;我发现唯一的区别是当没有名称时,rownames将打印“NULL”(与colnames相同),但row.names则不可见地返回它。由于两个函数之间没有太大的差异,rownames在美学方面更胜一筹,因为它与colnames更配得上。(此外,对于懒惰的程序员,你可以节省一个字符的输入。)


2

还有另一个扩展:

# create dummy matrix
set.seed(10)
m <- matrix(round(runif(25, 1, 5)), 5)
d <- as.data.frame(m)

如果您想要分配新的列名,您可以在 data.frame 上执行以下操作:

# an identical effect can be achieved with colnames()   
names(d) <- LETTERS[1:5]
> d
  A B C D E
1 3 2 4 3 4
2 2 2 3 1 3
3 3 2 1 2 4
4 4 3 3 3 2
5 1 3 2 4 3

如果你在matrix上运行之前的命令,会搞乱事情:
names(m) <- LETTERS[1:5]
> m
     [,1] [,2] [,3] [,4] [,5]
[1,]    3    2    4    3    4
[2,]    2    2    3    1    3
[3,]    3    2    1    2    4
[4,]    4    3    3    3    2
[5,]    1    3    2    4    3
attr(,"names")
 [1] "A" "B" "C" "D" "E" NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA 
[20] NA  NA  NA  NA  NA  NA 

由于矩阵可以被视为二维向量,因此您只需要给前五个值分配名称(您不想这样做,对吗?)。在这种情况下,您应该使用 colnames()

所以...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接