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

使用Tidyr Separate正则分割列:提取Y/N与额外信息

解决方案:拆分包含Y/N和注释的Surgery列

我明白你遇到的麻烦了——尝试用separate拆分Surgery列却没得到想要的结果,这是因为你的数据里有多种格式:纯Y/N、Y加连字符注释、还有完全没有Y/N的内容,默认的拆分规则没法覆盖所有情况。下面给你几个灵活的解决方案,都基于tidyverse工具实现:

首先先确认你的原始数据:

library(tidyverse)

df <- data.frame(Names=c("Patient1","patient2","Patient3","Patient4","patient5"),
                 Surgery=c("Y","N","Y-this kind of surgery","See note","Y"))

方法1:用str_extract和str_remove(最直观)

这个方法先提取开头的Y/N到新列,再移除Y/N和多余的连字符得到注释列,逻辑清晰容易调整:

df_processed <- df %>%
  mutate(
    # 提取开头的Y或N,没有则返回NA
    Surgery_YN = str_extract(Surgery, "^Y|^N"),
    # 移除开头的Y-、N-、Y、N,剩下的就是注释内容
    Notes = str_remove(Surgery, "^Y-|^N-|^Y|^N"),
    # 把空字符串的Notes转为NA(对应纯Y/N的行)
    Notes = ifelse(Notes == "", NA, Notes)
  )

print(df_processed)

输出结果:

Names               Surgery Surgery_YN                  Notes
1 Patient1                     Y          Y                     <NA>
2 patient2                     N          N                     <NA>
3 Patient3 Y-this kind of surgery          Y this kind of surgery
4 Patient4              See note       NA              See note
5 patient5                     Y          Y                     <NA>

方法2:用separate配合正则分隔符

如果偏好使用separate,可以利用正则的正向后顾断言来匹配Y/N后面的连字符,再处理无Y/N的行:

df_processed <- df %>%
  separate(Surgery, into = c("Surgery_YN", "Notes"),
           # 只匹配Y或N后面的连字符作为分隔符
           sep = "(?<=Y|N)-",
           # 没有注释的行填充NA
           fill = "right",
           # 多个分隔符时把剩余内容合并到Notes
           extra = "merge") %>%
  # 处理没有Y/N的行:把内容移到Notes,Surgery_YN设为NA
  mutate(
    Notes = case_when(
      !Surgery_YN %in% c("Y", "N") ~ Surgery_YN,
      TRUE ~ Notes
    ),
    Surgery_YN = ifelse(Surgery_YN %in% c("Y", "N"), Surgery_YN, NA)
  )

这个方法的输出和方法1完全一致。

方法3:用extract一次性匹配(最简洁)

extract可以通过正则表达式一次性捕获Y/N和注释内容,一步到位:

df_processed <- df %>%
  extract(Surgery, into = c("Surgery_YN", "Notes"),
          # 正则解释:
          # ^(Y|N)? 匹配开头可选的Y或N
          # (?:-(.*))? 可选的连字符加任意内容(非捕获组)
          regex = "^(Y|N)?(?:-(.*))?$",
          # 保留原Surgery列方便对比(可选,不需要可以去掉)
          remove = FALSE) %>%
  mutate(
    # 处理无Y/N的行:把原Surgery内容移到Notes,Surgery_YN设为NA
    Notes = ifelse(is.na(Surgery_YN), Surgery, Notes),
    Surgery_YN = ifelse(Surgery_YN %in% c("Y", "N"), Surgery_YN, NA)
  ) %>%
  # 移除原Surgery列(如果之前设置了remove=FALSE)
  select(-Surgery)

这个方法同样能得到符合需求的结果,适合喜欢简洁代码的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:31:27