在R语言中按指定位置拆分固定宽度字符串的最优方法
R语言按指定位置拆分长字符串的最优方法
问题背景
给定如下样本数据,需要将字符串按第2、4、10、14、16、18、19、23个字符后的位置拆分,输出固定分段的结果:
string1 <- c(320100000020220311020210) string2 <- c(320100000020220312120211) testitem <- data.frame(string1, string2)
关键前置处理
原数据中的字符串被存储为数值型,会丢失前导零,必须先转换为字符型:
testitem$string1 <- as.character(testitem$string1) testitem$string2 <- as.character(testitem$string2)
方法一:使用stringr包(简洁高效)
stringr的str_split_fixed函数可以直接按正则规则拆分并返回固定长度的结果:
library(stringr) # 定义拆分位置的正则表达式:匹配指定位置后的空字符串 split_pattern <- "(?<=^.{2})|(?<=^.{4})|(?<=^.{10})|(?<=^.{14})|(?<=^.{16})|(?<=^.{18})|(?<=^.{19})|(?<=^.{23})" # 拆分每个字符串,得到9段固定结果 split_str1 <- str_split_fixed(testitem$string1, split_pattern, n = 9) split_str2 <- str_split_fixed(testitem$string2, split_pattern, n = 9) # 合并为结果数据框 result <- rbind(split_str1, split_str2) colnames(result) <- paste0("分段_", 1:9) # 输出结果 print(result)
输出示例:
分段_1 分段_2 分段_3 分段_4 分段_5 分段_6 分段_7 分段_8 分段_9 [1,] "32" "01" "000000" "2022" "03" "11" "0" "2021" "0" [2,] "32" "01" "000000" "2022" "03" "12" "1" "2021" "1"
方法二:Base R原生实现(无需额外包)
使用Base R的strsplit配合Perl正则实现拆分:
# 定义拆分函数 split_func <- function(x) { strsplit(x, "(?<=^.{2})|(?<=^.{4})|(?<=^.{10})|(?<=^.{14})|(?<=^.{16})|(?<=^.{18})|(?<=^.{19})|(?<=^.{23})", perl = TRUE)[[1]] } # 应用拆分到所有字符串 result <- data.frame( t(sapply(testitem$string1, split_func)), t(sapply(testitem$string2, split_func)) ) colnames(result) <- c(paste0("string1_分段_", 1:9), paste0("string2_分段_", 1:9)) # 查看结果 print(result)
方法说明
- 正则表达式中的
(?<=^.{n})是正向预查断言,表示“匹配位于开头n个字符之后的空白位置”,通过|连接多个位置即可实现多断点拆分。 - 指定
n=9是因为8个拆分点会生成9个分段,确保结果结构固定,避免因字符串长度差异导致的错误。 - 若字符串长度固定,也可使用
substr逐个截取分段,但正则方法更灵活,修改拆分位置只需调整正则中的数字即可。
内容的提问来源于stack exchange,提问作者Tim Wilcox
相关产品推荐
相关产品推荐

