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

如何用多分隔符拆分列生成两列?排查R代码失效原因

代码无法正确运行的原因及修正方案

样本数据

k <- structure(list(Required.field = c("yes", "yes", "yes"),
                    Choices = c("2, Féminin | 1, Masculin", "1, Oui | 0, Non | 99, Je ne sais pas", "1, Oui | 0, Non")),
               row.names = c(5L, 10L, 15L), class = "data.frame") 

期望结果

> result

   Required.field            Number       Value
5             yes            c(2,1)       c(Féminin, Masculin)
10            yes            c(1,0,99)    c(Oui, Non, Je ne sais pas)
15            yes            c(1,0)       c(Oui, Non)

你的错误代码

k$test = strsplit(k$choice,c(" | "), fixed = T)


bbl = k %>% 
  mutate(number = str_extract_all(test, "[0-9]+")) %>% #get only digits
  mutate(value  = str_extract(test, "[aA-zZ].*")) #get only letters 

代码无法运行的原因

  • 列名拼写错误:数据里的列名是Choices(首字母大写、复数),但你写的是k$choice,这会导致strsplit找不到对应列,生成的test列全是NA,后续操作自然失效。
  • 分隔符匹配问题:你用" | "作为分隔符,但样本数据里的分隔符存在空格不一致的情况(比如第5行是|前无空格),加上fixed=T会严格匹配字符串,导致无法正确拆分所有选项。
  • 正则表达式与函数使用错误:
    1. test是列表类型的列(strsplit返回列表),直接用str_extract_all/str_extract处理列表列,无法正确遍历每个元素提取内容;
    2. 提取值的正则[aA-zZ].*范围错误,A-z会包含ASCII中A到z之间的符号(如[、\等),而且只能匹配第一个字母开头的片段,无法提取带空格的完整文本(比如Je ne sais pas);
    3. str_extract只会提取第一个匹配项,无法获取所有选项的值。

修正后的代码

如果要得到类似c(...)格式的字符串列,可以这样写:

library(tidyverse)

result <- k %>%
  # 拆分Choices为每个选项的列表,处理任意空格的|分隔符
  mutate(choices_split = str_split(Choices, "\\s*\\|\\s*")) %>%
  # 遍历每个拆分后的选项,提取数字和值
  mutate(
    Number = map_chr(choices_split, function(x) {
      nums <- str_extract(x, "\\d+") %>% paste(collapse = ",")
      paste0("c(", nums, ")")
    }),
    Value = map_chr(choices_split, function(x) {
      vals <- str_remove(x, "\\d+,\\s*") %>% paste(collapse = ", ")
      paste0("c(", vals, ")")
    })
  ) %>%
  select(Required.field, Number, Value)

print(result)

运行结果:

Required.field       Number                            Value
5             yes        c(2,1)             c(Féminin, Masculin)
10            yes     c(1,0,99) c(Oui, Non, Je ne sais pas)
15            yes        c(1,0)                  c(Oui, Non)

如果需要保留列表列(方便后续数值操作),可以去掉map_chr和拼接c(...)的部分:

result_list <- k %>%
  mutate(choices_split = str_split(Choices, "\\s*\\|\\s*")) %>%
  mutate(
    Number = map(choices_split, ~ str_extract(.x, "\\d+") %>% as.numeric()),
    Value = map(choices_split, ~ str_remove(.x, "\\d+,\\s*"))
  ) %>%
  select(Required.field, Number, Value)

print(result_list)

运行结果:

Required.field     Number                            Value
5             yes      2, 1             Féminin, Masculin
10            yes 1, 0, 99 Oui, Non, Je ne sais pas
15            yes      1, 0                  Oui, Non

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:15:57