修复以..x形式显示的列名:基于前置变量名处理调查数据集
修复调查数据集的列名结构问题(R data.table)
原始数据情况
读取后的数据集存在列名结构缺陷:
library(data.table) dat <- fread("q1 q2 ...1 ..2 q3 ..1 NA response other else response other 1 4 NA NA 1 NA") dat # q1 q2 ...1 ..2 q3 ..1 # 1: NA response other else response other # 2: 1 4 <NA> <NA> 1 <NA>
存在的问题
- 第一行实际是列名的补充部分,有效数据从第二行开始
- 命名为
...1、..2的列隶属于前面最近的q类问题列
已执行操作(未完成列名修复)
你已经完成了列名拼接和移除第一行,但未解决...1/..2类列的归属问题:
names(dat) <- paste0(names(dat), dat[1,]) dat <- dat[-1,] colnames(dat) <- sub("NA.*", "", colnames(dat)) dat # q1 q2response ...1other ..2else q3response ..1other # 1: 1 4 <NA> <NA> 1 <NA>
解决方案
以下代码可以将...1/..2类列名映射到对应的q类列,生成规范的下划线分隔列名:
library(data.table) # 重新读取原始数据(如果已经执行过前面的操作,可跳过这一步) dat <- fread("q1 q2 ...1 ..2 q3 ..1 NA response other else response other 1 4 NA NA 1 NA") # 提取第一行作为列名后缀 suffixes <- as.character(dat[1, ]) # 移除第一行无效数据 dat <- dat[-1, ] # 生成临时拼接列名 temp_names <- paste0(names(dat), suffixes) # 获取原始列名(未拼接前) orig_names <- names(dat) # 定位所有q开头的问题列位置 q_cols <- grep("^q\\d+", orig_names) # 初始化最终列名向量 final_names <- character(length(orig_names)) # 遍历每一列生成规范列名 for (i in seq_along(orig_names)) { if (i %in% q_cols) { # q类列直接保留拼接后无NA的名称 final_names[i] <- sub("NA.*", "", temp_names[i]) } else { # 找到当前列前最近的q类列作为父列 prev_q_col <- max(q_cols[q_cols < i]) # 提取父列的基础名称(如q2) parent_name <- sub("(^q\\d+).*", "\\1", orig_names[prev_q_col]) # 提取当前列的后缀(如other、else) col_suffix <- sub("^\\.+\\d+", "", temp_names[i]) # 拼接成规范格式:父列名_后缀 final_names[i] <- paste0(parent_name, "_", col_suffix) } } # 应用最终列名 setnames(dat, final_names) # 查看结果 dat # q1 q2_response q2_other q2_else q3_response q3_other # 1: 1 4 <NA> <NA> 1 <NA>
关键逻辑说明
- 用
grep("^q\\d+", orig_names)精准定位所有q开头的问题主列 - 遍历列时,非主列自动匹配最近的前置主列作为归属
- 通过正则提取主列名和子列后缀,用下划线连接成易读的规范列名
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

