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

使用dplyr::mutate结合str_detect处理舱位列提取异常问题

问题:dplyr处理cabin列生成新列时单组合场景结果异常

需求说明

需要用dplyr::mutate()创建新列cabin_zone,规则如下:

  • 当cabin列是单组字母+数字组合(如E4),提取字母部分(如E)
  • 当cabin列包含两组及以上组合(如F G73或B57 B59 B63 B66),提取所有唯一字母并用逗号分隔(如F,G或B)

数据样本

structure(list(pclass = c(1L, 1L, 1L, 3L, 3L), survived = c(0L, 
1L, 1L, 0L, 0L), name = c("Allison, Miss. Helen Loraine", "Anderson, Mr. Harry", 
"Andrews, Miss. Kornelia Theodosia", "Moen, Mr. Sigurd Hansen", 
"Soholt, Mr. Peter Andreas Lauritz Andersen"), sex = c("female", 
"male", "female", "male", "male"), age = c(2, 48, 63, 25, 19), 
    sibsp = c(1L, 0L, 1L, 0L, 0L), parch = c(2L, 0L, 0L, 0L, 
    0L), ticket = c("113781", "19952", "13502", "348123", "348124"
    ), fare = c(151.55, 26.55, 77.9583, 7.65, 7.65), cabin = c("C22 C26", 
    "E12", "D7", "F G73", "F G73"), embarked = c("S", "S", "S", 
    "S", "S"), boat = c("", "3", "10", "", ""), body = c(NA, 
    NA, NA, 309L, NA), home.dest = c("Montreal, PQ / Chesterville, ON", 
    "New York, NY", "Hudson, NY", "", ""), title = c("Miss.", 
    "Mr.", "Miss.", "Mr.", "Mr.")), row.names = c("3", "6", "7", 
"1025", "1218"), class = "data.frame")

用户代码

titanic_data <- titanic_data %>%
  mutate(cabin_zone = ifelse(str_detect(cabin," "),
                             cabin %>%
                               str_extract("[A-Z]") %>%
                               str_split(.," ") %>%
                               unlist(.) %>%
                               unique(.) %>%
                               paste(.,collapse = ","),
                             gsub("[0-9 ]", "", cabin)))

问题原因

问题出在向量化操作和逐行操作的冲突:
ifelse是向量化函数,要求三个参数的长度与输入列一致。但你在ifelse的TRUE分支中,对整个cabin列执行了链式操作,最终生成一个全局唯一的拼接字符串(所有舱位字母的集合,即'B,C,E,D,A,NA,T,F,G'),而非针对每个满足条件的行单独处理。当ifelse执行时,这个全局字符串会被循环填充到所有行,覆盖了单组合场景下gsub的正确结果。

解决方案

方法1:用case_when结合purrr::map_chr逐行处理

library(dplyr)
library(stringr)
library(purrr)

titanic_data <- titanic_data %>%
  mutate(cabin_zone = case_when(
    # 处理多组合场景:逐行提取每个舱位的字母,去重后拼接
    str_detect(cabin, " ") ~ map_chr(cabin, function(x) {
      x %>%
        str_split(" ") %>%
        unlist() %>%
        str_extract("[A-Z]") %>%
        unique() %>%
        paste(collapse = ",")
    }),
    # 处理单组合场景:移除数字,保留字母
    TRUE ~ str_remove_all(cabin, "[0-9]")
  ))

方法2:用rowwise()强制逐行执行操作

library(dplyr)
library(stringr)

titanic_data <- titanic_data %>%
  rowwise() %>%
  mutate(cabin_zone = ifelse(str_detect(cabin, " "),
                             cabin %>%
                               str_split(" ") %>%
                               unlist() %>%
                               str_extract("[A-Z]") %>%
                               unique() %>%
                               paste(collapse = ","),
                             str_remove_all(cabin, "[0-9]"))) %>%
  ungroup() # 取消逐行模式,恢复常规向量化操作

预期结果

运行上述代码后,cabin_zone列的结果为:

  • C22 C26 → C
  • E12 → E
  • D7 → D
  • F G73 → F,G
  • F G73 → F,G

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:33:29