You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R语言中利用正则表达式处理数据集并提取指定模式列?

R语言数据处理:提取特定模式列并重组数据集

原始数据集

id = 1:5
col1 = c("john", "henry", "adam", "jenna", "peter")
col2 = c("river B8C 9L4", "Field U9H 5E2 PP", "NA", "ocean A1B 5H1 dd", "dave")
col3 = c("matt", "steve", "forest K0Y 1U9 hu2", "NA", "NA")
col4 = c("Phone: 111 1111 111", "Phone: 222 2222", "Phone: 333 333 1113", "Phone: 444 111 1153", "Phone: 111 111 1121")
my_data = data.frame(id, col1, col2, col3, col4)

数据结构:

id  col1             col2               col3                col4
1  1  john    river B8C 9L4               matt Phone: 111 1111 111
2  2 henry Field U9H 5E2 PP              steve     Phone: 222 2222
3  3  adam               NA forest K0Y 1U9 hu2 Phone: 333 333 1113
4  4 jenna ocean A1B 5H1 dd                 NA Phone: 444 111 1153
5  5 peter             dave                 NA Phone: 111 111 1121

需求

  • 始终保留id列和col1列
  • 提取包含LETTER NUMBER LETTER NUMBER LETTER NUMBER模式的列内容生成new_col
  • 始终保留电话号码所在的col4列

期望结果

id  col1            new_col                col4
1  1  john      river B8C 9L4 Phone: 111 1111 111
2  2 henry  Field U9H 5E2 PP      Phone: 222 2222
3  3  adam forest K0Y 1U9 hu2 Phone: 333 333 1113
4  4 jenna      ocean A1B 5H1 Phone: 444 111 1153

现有正则代码

apply(my_data, 1, function(x) gsub('(([A-Z] ?[0-9]){3})|.', '\\1', toString(x)))
# 输出:[1] "B8C 9L4" "U9H 5E2" "K0Y 1U9" "A1B 5H1" ""   

解决方案

你的正则已经能定位目标模式,但需要匹配包含该模式的整段文本而非仅提取模式本身。以下是两种实现方式:

方法一:使用dplyr逐行处理

library(dplyr)

# 定义提取函数:保留包含目标模式的文本,清理多余后缀
extract_target <- function(str) {
  pattern <- "([A-Z][0-9][A-Z] [0-9][A-Z][0-9])"
  if (grepl(pattern, str)) {
    # 保留模式及前面的文本,去掉模式后多余的非有效字符
    return(sub("(.*[A-Z][0-9][A-Z] [0-9][A-Z][0-9])\\W.*", "\\1", str))
  } else {
    return(NA)
  }
}

# 处理数据集
my_result <- my_data %>%
  rowwise() %>%
  mutate(new_col = case_when(
    grepl("([A-Z][0-9][A-Z] [0-9][A-Z][0-9])", col2) ~ extract_target(col2),
    grepl("([A-Z][0-9][A-Z] [0-9][A-Z][0-9])", col3) ~ extract_target(col3),
    TRUE ~ NA_character_
  )) %>%
  select(id, col1, new_col, col4) %>%
  filter(!is.na(new_col))

print(my_result)

方法二:基础R实现(无依赖)

# 定义提取函数
extract_target <- function(str) {
  pattern <- "([A-Z][0-9][A-Z] [0-9][A-Z][0-9])"
  if (grepl(pattern, str)) {
    return(sub("(.*[A-Z][0-9][A-Z] [0-9][A-Z][0-9])\\W.*", "\\1", str))
  } else {
    return(NA)
  }
}

# 逐行生成new_col
new_col <- character(nrow(my_data))
for (i in 1:nrow(my_data)) {
  if (grepl("([A-Z][0-9][A-Z] [0-9][A-Z][0-9])", my_data$col2[i])) {
    new_col[i] <- extract_target(my_data$col2[i])
  } else if (grepl("([A-Z][0-9][A-Z] [0-9][A-Z][0-9])", my_data$col3[i])) {
    new_col[i] <- extract_target(my_data$col3[i])
  } else {
    new_col[i] <- NA
  }
}

# 组合结果并过滤无效行
my_result <- data.frame(
  id = my_data$id,
  col1 = my_data$col1,
  new_col = new_col,
  col4 = my_data$col4
) %>% filter(!is.na(new_col))

print(my_result)

代码说明

  1. 正则([A-Z][0-9][A-Z] [0-9][A-Z][0-9])精准匹配你需要的字母数字交替模式
  2. extract_target函数保留模式及前面的前缀文本,同时清理模式后的多余后缀(比如第4行的dd)
  3. 通过逐行判断col2和col3哪个包含目标模式,将对应内容赋值给new_col
  4. 最后保留指定列并过滤无匹配的行(比如第5行的peter)

内容的提问来源于stack exchange,提问作者stats_noob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:50:49