矩阵的R dimnames,行为奇怪

3
这是R中的一个bug还是有意为之?
## works
aa <- matrix(nrow=1,ncol=2)
dimnames(aa)[[2]] <- c("a","b")
dimnames(aa)[[1]] <- c("c")

## does not work
bb <- matrix(nrow=1,ncol=2)
dimnames(bb)[[1]] <- c("c")
Error in dimnames(bb)[[1]] <- c("c") : 'dimnames' must be a list

感谢您的解释!
3个回答

9

这是预期的行为。当你给对象中一个元素的索引分配值时,如果该元素不存在,R将创建该元素。在你的例子中,“dimnames”不存在于aa中,因此R尝试根据你所分配的内容创建“dimnames”。考虑给列表中以命名的元素"a"、"b"和"c"赋值:

> L <- list()
> L$a[[1]] <- 5
> L$b[[3]] <- "foo"
> L$c[[4]] <- c(1,2,3)
> class(L$a)
[1] "numeric"
> class(L$b)
[1] "character"
> class(L$c)
[1] "list"

现在使用L$a[[1]] <- anything的问题在于L$a尚不存在。当元素不存在时,R会创建最简单的可以工作的元素。如你所见,如果L$a是数字向量,则L$a[[1]] <- 5是有意义的,因此R将其创建为数字向量。如果L$b是数字向量,则L$b[[3]] <- "foo"是没有意义的,但如果L$b是字符向量,则它是有意义的,因此R将其创建为字符向量。但是,只有当L$c是列表时,L$c[[4]] <- c(1,2,3)才能发生,因此在这种情况下,您将得到一个列表。
在您的情况下,它尝试根据该规则创建dimnames。因此,它使dimnames(aa)成为一个列表,但它只使dimnames(bb)成为一个字符向量。但是,dimnames有一个额外的约束条件,即它必须是一个列表,因此它会出错并出现错误。

1

您可以使用

dimnames(bb)[[1]] <- list("c")

这个命令将把名称分配为行名。

我想错误是由于未创建dimnames列表造成的。否则,如果您先访问列表的第二部分([[2]]),则列表将被创建。因此,您之后也可以访问dimnames[[1]]


我其实很惊讶这个能够运行;aa$b[[1]] <- list("c") 会使 aa$b 成为一个包含列表的列表,这并不是你在使用 dimnames 时想要的结果。使用单括号即 dimnames(aa)[1] <- list("c") 也可以运行,并且更符合 R 在其他地方的行为一致性。 - crowding
@crowding 我同意,使用单括号更加一致。但实际上,dimnames(aa)[1] <- list("c")dimnames(aa)[[1]] <- list("c")的结果是相同的。 - Sven Hohenstein

0

我会按照错误提示所说的去做:

dimnames(bb)[[1]] <- list("c")
> bb
  [,1] [,2]
c   NA   NA

还有其他可行的方法:

dimnames(bb)[[1]] <- "c"

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