为何对R数据框执行子集化操作会修改其原有的重复列名?
重复列名被自动重命名的原因
这个现象由R数据框的两个核心构造规则决定:
check.names参数仅在数据框构造的当下生效,不会作为永久属性绑定到数据框实例- 所有列维度的子集操作,本质上都会触发一次新数据框的构造流程,未显式指定参数时将使用函数内置默认值
流程对应解释
- 最初构造原始数据框
DF时,你手动设置check.names = FALSE,等价于告知R:本次构造过程中不要自动校验、修正列名。因此即便出现两个完全同名的danger列,R也会原样保留列名,不做任何调整。 - 执行列筛选操作
DF[!(names(DF) %in% drops)]时,R不会直接返回原数据框中截取的列内存块,而是会把筛选出的列打包,重新调用data.frame()函数构造一个全新的数据框。这次构造没有手动传入check.names参数,因此会调用R内置的默认值*check.names = TRUE*。 - 当
check.names = TRUE时,R会自动执行列名合规性校验:为所有重复列名按出现顺序追加.1、.2……的后缀,保证列名全局唯一。这就是第二个danger列被自动重命名为danger.1的直接原因。
快速验证
如果在子集化时显式关闭列名校验,即可保留原有重复列名,运行以下代码即可复现无重命名的效果:
DF[!(names(DF) %in% drops), check.names = FALSE]
此时输出的列名将保持为y、danger、danger,不会出现自动生成的danger.1列名。
内容的提问来源于stack exchange,提问作者J. Mini
相关产品推荐
相关产品推荐

