R语言字符串拆分问题:可变分隔符分2列及多格式列拆3列
刚好我经常处理这类字符串拆分的需求,来给你详细解答这两个R语言的问题:
问题1:分隔符不固定时,把单个字符串列拆分为2列
当分隔符是不固定的(比如数量不一的空格、连字符、混合符号),用正则表达式配合tidyr或stringr包的工具是最灵活的方案,给你两种常用方法:
方法1:用tidyr::separate_wider_regex(可读性拉满)
这个函数可以直接用正则匹配模式来定义拆分规则,特别适合分隔符不固定的场景。比如假设你有个数据框df,里面的text列内容是类似"Alice---Smith" "Bob--Johnson" "Charlie-Davis"这种,分隔符是1个或多个-:
library(tidyr) # 先整个示例数据 df <- data.frame(text = c("Alice---Smith", "Bob--Johnson", "Charlie-Davis")) # 拆分操作:匹配非连字符内容→多个连字符→剩余内容,拆成两列 df_split <- df %>% separate_wider_regex( text, patterns = list(col1 = "[^-]+", sep = "-+", col2 = ".+") )
解释下正则:[^-]+抓第一部分非连字符的内容,-+匹配1个及以上的连字符当成分隔符,.+抓剩下的所有内容作为第二列。
方法2:用stringr::str_split_fixed
要是你更习惯stringr的语法,用这个函数也很方便:
library(stringr) library(dplyr) df_split <- df %>% mutate( col1 = str_split_fixed(text, "-+", 2)[,1], col2 = str_split_fixed(text, "-+", 2)[,2] ) %>% select(-text)
str_split_fixed里的-+是正则分隔符(匹配1个或多个连字符),第三个参数2指定拆成2列,最后删掉原列就行。
问题2:拆分actorsdata的ActorName列为姓名、Born、Died三列
这个场景的麻烦在于括号内容格式不统一,有的是生卒年,有的是带"born"的出生信息,还有额外括号。我们分两步来处理,稳得很:
第一步:先提取演员姓名
姓名就是第一个括号前面的内容,我们用正则抓出来再去掉末尾的空格:
library(dplyr) library(stringr) actorsdata <- actorsdata %>% mutate( `Actor Name` = str_trim(str_extract(ActorName, "^[^(]+")) )
^[^(]+的意思是从字符串开头,抓到第一个(之前的所有内容,str_trim是去掉姓名前后可能的空格。
第二步:提取出生和死亡年份
针对两种常见格式,我们用正则分别匹配:
- 格式1:
(1944–2012)→ 抓1944当Born,2012当Died - 格式2:
(born 1942)→ 抓1942当Born,Died留空
直接上代码:
actorsdata <- actorsdata %>% mutate( # 抓出生年份:匹配"born "后面的4位数字,或者"(年份–"里的年份 Born = str_extract(ActorName, "(?<=born )\\d{4}|^\\((\\d{4})–"), Born = str_remove(Born, "^\\("), # 去掉可能带的开头括号 # 抓死亡年份:匹配"–年份)"里的年份 Died = str_extract(ActorName, "(?<=–)\\d{4}(?=\\))") )
解释下关键正则:
(?<=born )\\d{4}:这是正向预查,专门抓"born "后面的4位数字(?<=–)\\d{4}(?=\\)):前后都加预查,抓–和)之间的4位数字,也就是死亡年份
测试下示例数据
我给你整个测试数据试试效果:
actorsdata <- data.frame(ActorName = c( "Angharad Rees (1944–2012)", "Anna Carteret (born 1942) (born in Bangalore, India)", "John Doe (1950–)", "Jane Smith (born 1965)" ))
运行完代码后,结果会是这样:
| ActorName | Actor Name | Born | Died |
|---|---|---|---|
| Angharad Rees (1944–2012) | Angharad Rees | 1944 | 2012 |
| Anna Carteret (born 1942) (born in Bangalore, India) | Anna Carteret | 1942 | NA |
| John Doe (1950–) | John Doe | 1950 | NA |
| Jane Smith (born 1965) | Jane Smith | 1965 | NA |
补充:处理特殊情况
如果遇到没有括号的行,或者其他奇怪格式,加个判断让结果更干净:
actorsdata <- actorsdata %>% mutate( Born = ifelse(is.na(Born), NA, Born), Died = ifelse(is.na(Died), NA, Died) )
内容的提问来源于stack exchange,提问作者qwertykeyboard
相关产品推荐
相关产品推荐

