如何基于代码范围条件创建22个章节标识变量(R语言)
问题描述与解决方案
给定数据
原数据集
data <- data.frame(DO = c("205145", "587523", '484351', "453475", "456546", "15641334", "465466", '674646', "564635", "65255"), LINHAA2 = c("A150", "B250", "D349", "T980", "R99", "O988", "L99", "Q220", "F530", "P88"), LINHAA3 = c("A445", "K098", "G87", "I10", "A240", "Q88", "V633", "Z100", "I340", "L260"), LINHAA4 = c("K213", "A123", "U876", "X999", "O150", "A765", "Z987", "G543", "P987", "Z100"), LINHAA5 = c("Q098", "K098", "L987", "J988", "C192", "S234", "V123", "P098", "N976", "V199"))
章节编码范围
chapters <- data.frame(chapter = 1:22, code = c("A000-B999", "C000-D489", "D500-D899", "E000-E900", "F000-F999", "G000-G998", "H000-H599", "H600-H959", "I000-I999", "J000-J998", "K000-K938", "L000-L998", "M000-M999", "N000-N999", "O000-O998", "P000-P969", "Q000-Q999", "R000-R999", "S000-T980", "V010-Y989", "Z000-Z999", "U000-U859"))
需求
为每个章节创建变量(命名为CHAPTER1至CHAPTER22):
- 若某行中任意
LINHAA前缀的编码属于该章节的代码范围,变量赋值为1; - 否则赋值为0;无匹配编码的章节变量全部填充0。
示例:第一行的A150、A445属于章节1,故CHAPTER1为1,CHAPTER2为0。
解决方案代码
# 加载所需包(未安装先运行 install.packages(c("tidyr", "dplyr"))) library(tidyr) library(dplyr) # 原数据集(已定义可跳过) data <- data.frame(DO = c("205145", "587523", '484351', "453475", "456546", "15641334", "465466", '674646', "564635", "65255"), LINHAA2 = c("A150", "B250", "D349", "T980", "R99", "O988", "L99", "Q220", "F530", "P88"), LINHAA3 = c("A445", "K098", "G87", "I10", "A240", "Q88", "V633", "Z100", "I340", "L260"), LINHAA4 = c("K213", "A123", "U876", "X999", "O150", "A765", "Z987", "G543", "P987", "Z100"), LINHAA5 = c("Q098", "K098", "L987", "J988", "C192", "S234", "V123", "P098", "N976", "V199")) # 章节编码范围(已定义可跳过) chapters <- data.frame(chapter = 1:22, code = c("A000-B999", "C000-D489", "D500-D899", "E000-E900", "F000-F999", "G000-G998", "H000-H599", "H600-H959", "I000-I999", "J000-J998", "K000-K938", "L000-L998", "M000-M999", "N000-N999", "O000-O998", "P000-P969", "Q000-Q999", "R000-R999", "S000-T980", "V010-Y989", "Z000-Z999", "U000-U859")) # 定义编码补全函数:将短编码转为"字母+3位数字"的标准格式 pad_code <- function(x) { letter <- substr(x, 1, 1) num_part <- substr(x, 2, nchar(x)) num_padded <- sprintf("%03d", as.integer(num_part)) paste0(letter, num_padded) } # 统一所有LINHAA列的编码格式 linhaa_columns <- grep("^LINHAA", names(data)) data[, linhaa_columns] <- lapply(data[, linhaa_columns], pad_code) # 拆分章节范围为起始、结束编码,并补全格式 chapters_processed <- chapters %>% separate(code, into = c("start_code", "end_code"), sep = "-") %>% mutate(start_code = pad_code(start_code), end_code = pad_code(end_code)) # 循环生成每个章节的标识变量 for (row_idx in 1:nrow(chapters_processed)) { chap_number <- chapters_processed$chapter[row_idx] start <- chapters_processed$start_code[row_idx] end <- chapters_processed$end_code[row_idx] # 逐行检查是否有编码落在当前章节范围内,生成0/1值 data[[paste0("CHAPTER", chap_number)]] <- apply(data[, linhaa_columns], 1, function(row_values) { any(row_values >= start & row_values <= end) }) %>% as.integer() } # 查看处理后的数据集前几行 head(data)
代码说明
- 编码补全:
pad_code函数将R99这类短编码转为R099,保证字符串比较的一致性(按字母顺序+数字大小逻辑比较); - 章节范围解析:拆分每个章节的编码范围为起始和结束值,同样补全格式;
- 生成标识变量:循环每个章节,用
apply逐行检查是否存在符合范围的编码,将布尔值转为整数0/1,最终合并到原数据集。
内容的提问来源于stack exchange,提问作者Lana Meijinhos
相关产品推荐
相关产品推荐

