如何自动为数据框的批量长列名分配短名称?
自动批量重命名数据框列名(处理相似列名)
我有一个含约300列的数据集,列名都是冗长的问题,手动重命名工作量太大,希望能自动完成,同时处理列名高度相似的变体情况。
初始数据示例:
col_names <- c("How old are your parents ?", "How old is your sister ?", "What dessert did you eat yesterday ? [Option1]", "What dessert did you eat yesterday ? [Option2]", "What dessert did you eat yesterday ? [Option3]", "What color is your shirt ? [Option 1]", "What color is your shirt ? [Option 2]") data <- data.frame(matrix(ncol = length(col_names), nrow = 2)) colnames(data) <- col_names
需求1:保留选项后缀的重命名
期望将列名重命名为如下形式:
col_names <- c("A", "B", "C[Option1]", "C[Option2]","C[Option3]", "D[Option 1]", "D[Option 2]") data <- data.frame(matrix(ncol = length(col_names), nrow = 2)) colnames(data) <- col_names
需求2:简化为字母+数字的重命名
额外需求:是否可以重命名为以下样式?
col_names <- c("A", "B", "C1", "C2","C3", "D1", "D2") data <- data.frame(matrix(ncol = length(col_names), nrow = 2)) colnames(data) <- col_names
解决方案1:保留选项后缀的自动重命名
核心思路是提取列名的主体部分(移除选项后缀),为每个唯一主体分配字母标签,再拼接原选项后缀:
library(stringr) # 提取列名的主体部分(去掉[Option...]后缀) main_parts <- str_remove(colnames(data), "\\s*\\[Option.*\\]") # 为每个唯一主体分配字母标签 unique_mains <- unique(main_parts) letter_labels <- setNames(LETTERS[1:length(unique_mains)], unique_mains) # 提取选项后缀(无后缀的设为空字符串) option_suffixes <- str_extract(colnames(data), "\\[Option.*\\]") option_suffixes[is.na(option_suffixes)] <- "" # 拼接生成新列名并应用 new_colnames1 <- paste0(letter_labels[main_parts], option_suffixes) colnames(data) <- new_colnames1
解决方案2:简化为字母+数字的重命名
对同一主体的列分组编号,拼接字母与编号生成简洁列名,提供两种实现方式:
方式1:使用tidyverse工具
library(dplyr) library(tibble) library(stringr) # 处理列名生成新名称 new_colnames2 <- data %>% colnames() %>% tibble(old_name = .) %>% mutate(main_part = str_remove(old_name, "\\s*\\[Option.*\\]")) %>% group_by(main_part) %>% mutate( seq_num = row_number(), letter = LETTERS[match(main_part, unique(main_part))], new_name = ifelse(n() == 1, letter, paste0(letter, seq_num)) ) %>% pull(new_name) # 应用新列名 colnames(data) <- new_colnames2
方式2:Base R实现(无需额外包)
# 提取列名主体部分 main_parts <- gsub("\\s*\\[Option.*\\]", "", colnames(data)) # 为每个唯一主体分配字母 unique_mains <- unique(main_parts) letter_map <- LETTERS[1:length(unique_mains)] names(letter_map) <- unique_mains # 对同一主体的列进行分组编号 group_ids <- match(main_parts, unique_mains) seq_nums <- ave(rep(1, length(main_parts)), group_ids, FUN = seq_along) group_sizes <- ave(rep(1, length(main_parts)), group_ids, FUN = length) # 生成新列名并应用 new_colnames2 <- ifelse(group_sizes == 1, letter_map[main_parts], paste0(letter_map[main_parts], seq_nums)) colnames(data) <- new_colnames2
内容的提问来源于stack exchange,提问作者Muller I.
相关产品推荐
相关产品推荐

