为何tibble为单列矩阵生成的新列添加[,1]后缀?
为啥把单列矩阵加到tibble里,列名变成
rn[,1]了? 这真不是tibble的bug,而是它刻意设计的行为——核心逻辑是tibble会尽可能保留输入数据的维度结构,避免像基础R数据框那样自动把单列矩阵/数组“压扁”成向量。
具体来唠唠原因:
- 矩阵天生是二维结构:哪怕只有一列,它也同时具备行和列两个维度。在基础R里,如果你直接取单列矩阵(比如
mat[,1]),R会自动把它降维成向量(除非你加drop=FALSE);但tibble在处理这类赋值时,会死死守住原始的二维结构。 - 列名的生成规则:当你给tibble传入一个没有自定义列名的单列矩阵时,tibble会用矩阵的位置索引(
[,1])来标记这个二维结构的来源,最终拼成你指定的列名[,1]的形式,说白了就是在告诉你:“这列是从一个二维矩阵的第一列来的哦”。
举几个例子对比下就懂了:
直接创建tibble的场景:
tibble::tibble(rn = matrix(rep(1, 5), ncol = 1))这里tibble一眼就认出
rn对应的是个二维矩阵,所以直接把矩阵的列索引挂到变量名后面,生成了rn[,1]这个列名。用降维后的向量/多列矩阵的情况:
要是你先把矩阵的单列转成向量(比如mat[,1],基础R默认会降维),或者用多列矩阵,tibble就会按常规逻辑处理列名:df <- tibble::tibble(let = letters[1:5]) mat <- matrix(1:10, ncol = 2) df[, "mat1"] <- mat[, 1] # 这里mat[,1]是向量,所以列名正常显示mat1转成data.frame为啥就正常了:
当你把单列矩阵转成data.frame时,data.frame会自动把矩阵的列转换成向量(还会默认给个列名V1),这时候再赋值给tibble,tibble就会用你指定的列名(mat2)覆盖掉默认的V1,所以最终列名就正常啦:df[, "mat2"] <- as.data.frame(mat2)
给你几个更省事的解决办法:
不想转data.frame也能得到正常列名,只要把单列矩阵降维成向量就行:
# 方法1:用as.vector直接转成向量 df[, "mat2"] <- as.vector(mat2) # 方法2:提取时明确降维(其实默认就是drop=TRUE,可省略) df[, "mat2"] <- mat2[, 1, drop=TRUE] # 方法3:用add_column函数,明明白白指定列名 df <- df %>% tibble::add_column(mat2 = mat2[,1])
内容的提问来源于stack exchange,提问作者Jake Fisher
相关产品推荐
相关产品推荐

