R语言如何基于分隔符和位置将单列拆分为三列
问题核心原因
tidyr::separate未手动指定分隔规则时,默认以任意非字母数字字符(含空格、短横、括号)作为分割点,会把位置名称里的空格识别成分隔符,最终拆分错位。
观察location列的固定结构:
- 字段最前端由短横连接的两段编码为
code,格式如01-Q2 - 第二个短横之后、末尾括号之前的文本为
name,允许包含空格 - 末尾括号内的两位大写字母为
region
推荐解法
用tidyr::extract通过正则分组精准匹配三个字段,不受名称内空格干扰,结果最稳定:
library(dplyr) library(tidyr) # 构造示例数据集 data.1 <-read.csv(text = " location 01-Q2-Locate of este (TT) 02-Q2-Green River (OG) 01-Q1-Agabe (PS) ") # 拆分列 data.1.new <- data.1 %>% extract( col = location, into = c("code", "name", "region"), regex = "^([0-9]{2}-Q[12])-(.*) \\(([A-Z]{2})\\)$", remove = FALSE )
运行后输出结果完全匹配预期:
| location | code | name | region |
|---|---|---|---|
| 01-Q2-Locate of este (TT) | 01-Q2 | Locate of este | TT |
| 02-Q2-Green River (OG) | 02-Q2 | Green River | OG |
| 01-Q1-Agabe (PS) | 01-Q1 | Agabe | PS |
如果需要沿用separate函数,可手动指定分隔符的正则匹配规则,避免误拆名称内的空格:
data.1.new2 <- data.1 %>% separate( col = location, into = c("code", "name", "region"), sep = "(?<=^[0-9]{2}-Q[12])-| \\(|\\)$", remove = FALSE ) %>% # 移除正则拆分产生的空值行 filter(!is.na(region))
匹配规则说明
^([0-9]{2}-Q[12]):捕获字符串开头两位数字+-Q+1/2的编码段,对应code-(.*):匹配编码段后的短横,捕获后续到括号前空格为止的所有文本,对应name\\(([A-Z]{2})\\)$:捕获字符串末尾括号包裹的两位大写字母,对应region
内容的提问来源于stack exchange,提问作者Giuseppe Petri
相关产品推荐
相关产品推荐

