如何使用tidyr将字符串拆分至四列?正则表达式实现求助
R语言数据框列拆分解决方案
针对你提供的数据框,我们可以使用tidyr包的extract()函数,通过正则表达式一次性将A列拆分为指定的四列(ID1、ID2、姓名、属性)。以下是具体实现:
代码实现
# 加载tidyr包 library(tidyr) # 原始数据框 dat <- data.frame( A = c("M24656811 M24677722 GREEN,SMITH34/M/B", "M24654999 DOE,JANE V37/F/W", "M24333107 DOE,JOHN24/M/B") ) # 拆分列 dat_split <- dat %>% extract( col = A, into = c("ID1", "ID2", "Name", "Attr"), regex = "^([M0-9]+)(?:\\s+([M0-9]+))?\\s+([A-Za-z,]+?)(?:\\s+)?([A-Z0-9]+/[A-Z]/[A-Z])$", remove = FALSE # 可选,保留原A列便于验证 ) # 查看结果 print(dat_split)
正则表达式说明
正则表达式的每个分组对应拆分后的一列:
^([M0-9]+):捕获第一个以M开头的编号(ID1)(?:\\s+([M0-9]+))?:可选捕获第二个以M开头的编号(ID2),没有则返回NA([A-Za-z,]+?):非贪婪捕获姓名(包含字母和逗号),避免把属性部分的数字包含进来([A-Z0-9]+/[A-Z]/[A-Z]):捕获属性部分(格式为「标识/性别/种族」)- 非捕获组
(?:...)用于包裹可选或辅助匹配的内容,不会生成额外列
分步拆分方案(可选)
如果你觉得一次性正则表达式太复杂,也可以分步拆分:
# 第一步:拆分ID部分和姓名属性部分 dat_step1 <- dat %>% separate(A, into = c("IDs", "NameAttr"), sep = "\\s+(?=[A-Za-z,])", extra = "merge") # 第二步:拆分ID为ID1和ID2 dat_step2 <- dat_step1 %>% separate(IDs, into = c("ID1", "ID2"), sep = "\\s+", fill = "right") # 第三步:拆分姓名和属性 dat_final <- dat_step2 %>% extract(NameAttr, into = c("Name", "Attr"), regex = "([A-Za-z,]+?)(?:\\s+)?([A-Z0-9]+/[A-Z]/[A-Z])")
内容的提问来源于stack exchange,提问作者Lihui Zhang
相关产品推荐
相关产品推荐

