使用tidyverse函数在R中按字符串模式拆分列
从含多分隔符的字符串中提取首尾段生成新列
需求说明
需要从给定的DATA数据框的tor列生成两列:
- ID1:提取字符串中第一个
-之前的所有内容,以字符型输出 - ID2:提取字符串中最后一个
-之后的所有内容,以字符型输出
需自动处理单元格含多个-以及NA的情况,最终输出格式如下:
| val | ID1 | ID2 | food |
|---|---|---|---|
| 1 | 0001 | U.S.A1 | pizza |
| 2 | 0023 | ?2MALTA | pasta |
| 3 | 009876 | !HUNGARY | berger |
| 4 | NA | NA | pizza |
原始数据
val = c(1,2,3,4) tor = c( "0001-NEW YORK - M.AVENUE, NY-U.S.A1", "0023-cARAVAGGIO-NICOLO-PERUGIA-?2MALTA", "009876-bUDAPEST-!HUNGARY" ,NA) food = c("pizza","pasta","berger","pizza") DATA = tibble(val,tor,food)
解决方案
方法一:使用tidyverse生态(推荐,适配tibble)
借助stringr包的正则匹配功能,高效实现需求:
library(tidyverse) DATA_processed <- DATA %>% mutate( # 提取第一个-前的所有内容 ID1 = str_extract(tor, "^[^-]+"), # 提取最后一个-后的所有内容 ID2 = str_extract(tor, "[^-]+$") ) %>% # 显式转换为字符型,避免因子类型问题 mutate(across(c(ID1, ID2), as.character)) # 查看结果 print(DATA_processed)
代码解释:
^[^-]+:正则表达式表示从字符串开头匹配所有非-字符,直到第一个-终止,精准提取ID1[^-]+$:正则表达式表示匹配所有非-字符直到字符串结尾,对应最后一个-后的内容,即ID2across():批量处理两列,确保输出为字符型
方法二:基础R实现(无额外依赖)
用strsplit拆分字符串后提取首尾元素:
# 生成ID1列 DATA$ID1 <- sapply(DATA$tor, function(x) { if (is.na(x)) return(NA_character_) strsplit(x, "-")[[1]][1] }) # 生成ID2列 DATA$ID2 <- sapply(DATA$tor, function(x) { if (is.na(x)) return(NA_character_) parts <- strsplit(x, "-")[[1]] parts[length(parts)] }) # 转换为字符型 DATA$ID1 <- as.character(DATA$ID1) DATA$ID2 <- as.character(DATA$ID2)
内容的提问来源于stack exchange,提问作者Homer Jay Simpson
相关产品推荐
相关产品推荐

