如何用多分隔符拆分列生成两列?排查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会严格匹配字符串,导致无法正确拆分所有选项。 - 正则表达式与函数使用错误:
test是列表类型的列(strsplit返回列表),直接用str_extract_all/str_extract处理列表列,无法正确遍历每个元素提取内容;- 提取值的正则
[aA-zZ].*范围错误,A-z会包含ASCII中A到z之间的符号(如[、\等),而且只能匹配第一个字母开头的片段,无法提取带空格的完整文本(比如Je ne sais pas); 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
相关产品推荐
相关产品推荐

