如何阻止dplyr::select合并名称,实现直接分配新列名?
解决dplyr select中用命名向量选列并重命名时的名称拼接问题
问题重现
当使用命名向量在dplyr::select()中同时选择列并重命名时,dplyr会自动拼接新名称与向量原名称,导致出现类似time...period的复合列名,而非预期的单独新名称。示例代码如下:
# dplyr ‘1.1.2’ # R Version 4.3.0 data <- data.frame(day = 1, week = 2, n_in_year = 365) new_values <- c(period = "day", n = 365) # 得到拼接后的列名:time...period data %>% dplyr::select(time = new_values[1]) # 期望的效果(两步操作) data %>% dplyr::select(new_values[1]) %>% dplyr::rename(time = period)
原因分析
new_values[1]是一个带名称的字符向量(值为"day",名称为period),dplyr的select()在处理新名称 = 命名向量这种语法时,会默认将左侧的新名称与右侧向量的原有名称拼接,以此保留向量的元信息,这就导致了复合列名的出现。
解决方案
只需移除右侧命名向量的名称信息,让select()仅使用你指定的新名称即可,以下是几种简洁的实现方式:
- 方法1:使用
unname()去除向量名称
直接去掉new_values[1]的名称属性,避免名称拼接:
data %>% dplyr::select(time = unname(new_values[1]))
- 方法2:使用
all_of()指定列选择all_of()会提取向量的字符值并忽略其名称,适合处理字符型列名的选择:
data %>% dplyr::select(time = all_of(new_values[1]))
- 方法3:转换为纯字符值
通过as.character()直接提取向量的字符内容,丢弃名称:
data %>% dplyr::select(time = as.character(new_values[1]))
以上三种方法都能一步得到预期结果,列名直接为time,无需先select再rename。
内容的提问来源于stack exchange,提问作者JCran
相关产品推荐
相关产品推荐

