as.matrix 后行名称消失

Row names disappear after as.matrix

我注意到如果数据框的行名称遵循从 1 到行数的数字序列。使用 as.matrix 后数据框的行名将消失。但如果行名不是序列,行名会重新出现。

这是一个可重现的例子:

test <- as.data.frame(list(x=c(0.1, 0.1, 1), y=c(0.1, 0.2, 0.3)))
rownames(test)
# [1] "1" "2" "3"

rownames(as.matrix(test))
# NULL

rownames(as.matrix(test[c(1, 3), ]))
# [1] "1" "3"

有人知道发生了什么事吗?

非常感谢

我不知道为什么会这样,但解决它的一种方法是在 as.matrix

中包含参数 rownames.force = T
rownames(as.matrix(test, rownames.force = T))

首先,我们总是有一个 sub-setting 的数字索引,它不会消失,我们不应该与行 names.[=21= 混淆]

as.matrix(test)[c(1, 3), ]
#        x   y
# [1,] 0.1 0.1
# [2,] 1.0 0.3

使用 rownames 时发生的事情是 base:::rownames()

的宁静源代码中的 dimnames 功能
function (x, do.NULL = TRUE, prefix = "row") 
{
  dn <- dimnames(x)
  if (!is.null(dn[[1L]])) 
    dn[[1L]]
  else {
    nr <- NROW(x)
    if (do.NULL) 
      NULL
    else if (nr > 0L) 
      paste0(prefix, seq_len(nr))
    else character()
  }
}

对于 dimnames(as.matrix(test))[[1]] 产生 NULL 但在 dimnames(as.matrix(test[c(1, 3), ]))[[1]] 的情况下产生 "1" "3"

请注意,方法 base:::row.names.data.frame 适用于数据帧,例如rownames(test).

WHAT应该用它来解释,幸运的是你没有问WHY,而是opinion-based。

数据帧与矩阵的差异:

?行名

rownames(x, do.NULL = TRUE, prefix = "row")

重要的部分是 do.NULL = TRUE 默认值为 TRUE:这意味着:

如果do.NULL为FALSE,无论如何都会返回一个字符向量(长度为NROW(x)或NCOL(x)),

如果在没有任何现有 dimnames 的矩阵上调用替换版本,它们将添加合适的 dimnames。但是

这样的结构
rownames(x)[3] <- "c"

除非 x 已经有 dimnames,否则可能无法工作,因为这将从 rownames(x) 的 NULL 值创建一个长度为 3 的值。

对我来说,这意味着(可能不正确或不专业)将 rownames() 函数应用于矩阵,必须先声明行的维度,否则你将得到 NULL -> 因为这是函数中的默认设置rownames().

在您的示例中,您遇到了这种行为: 在这里声明第 1 行和第 3 行并获得 1 和 3

rownames(as.matrix(test[c(1, 3), ]))
[1] "1" "3"

在这里你什么都不声明并得到 NULL 因为 NULL 是默认值。

rownames(as.matrix(test))
NULL

您可以通过在之前声明来解决这个问题:

rownames(test) <- 1:3

rownames(as.matrix(test))
[1] "1" "2" "3"

或者你可以这样做:

rownames(as.matrix(test), do.NULL = FALSE)
[1] "row1" "row2" "row3"
> rownames(as.matrix(test), do.NULL = FALSE, prefix="")
[1] "1" "2" "3"

与rownames.force类似的效果: rownames.force
逻辑指示结果矩阵是否应具有字符(而不是 NULL)行名。如果数据框具有“自动”row.names 或 zero-row 数据框,则默认值 NA 使用 NULL 行名。 dimnames(matrix_test)

申请时可以启用rownames = TRUEas.matrix

> as.matrix(test, rownames = TRUE)
    x   y
1 0.1 0.1
2 0.1 0.2
3 1.0 0.3

'automatic' 和非 'automatic' 行名称之间存在差异。

这是一个激励人心的例子:

自动

test <- as.data.frame(list(x = c(0.1,0.1,1), y = c(0.1,0.2,0.3)))
rownames(test)
# [1] "1" "2" "3"

rownames(as.matrix(test))
# NULL

非'automatic'

test1 <- test
rownames(test1) <- as.character(1:3)
rownames(test1)
# [1] "1" "2" "3"

rownames(as.matrix(test1))
# [1] "1" "2" "3"

您可以在例如?data.frame,最后提到你发现的行为:

If row.names was supplied as NULL or no suitable component was found the row names are the integer sequence starting at one (and such row names are considered to be ‘automatic’, and not preserved by as.matrix).

当您调用 test[c(1, 3), ] 时,您会隐式创建非 'automatic' 行名,这在 ?Extract.data.frame:

中有记录

If `[` returns a data frame it will have unique (and non-missing) row names.

(如果您想深入了解,请在您的控制台中输入 `[.data.frame`。)

其他人已经说明了这对您的情况意味着什么,请参阅 ?matrix 中的参数 rownames.force:

rownames.force: ... The default, NA, uses NULL rownames if the data frame has ‘automatic’ row.names or for a zero-row data frame.