tidyverse中extract函数适配不同长度记录失败及动态列名求助
问题解答
1. 解决extract第二行提取失败的问题
你的正则写死了6个捕获组,但第二行字符串只有3个分割段(2个下划线),匹配不上6个组,所以提取失败。
两种解决方式:
方式一:调整extract的正则,让后续组可选
把后面的捕获组改成可选匹配,允许空值,正则里用(?:_(.+))?表示非捕获的可选组:
library(tidyverse) test_data <- data.frame(category=c("az_b1_wj_1_k_z","f_2_wj")) test_data %>% extract(category, LETTERS[1:6], "(.+)_(.+)_(.+)(?:_(.+))?(?:_(.+))?(?:_(.+))?")
这样不管字符串是3段还是6段都能匹配,不足的列会填充NA。
方式二:改用separate函数(更适合固定分隔符的场景)
separate专门处理分割字符串,默认会自动补NA,比extract更省心:
test_data %>% separate(category, into = LETTERS[1:6], sep = "_", fill = "right")
fill = "right"表示右边缺的列补NA,要补左边就改成fill = "left"。
2. 实现动态列名
完全可以用LETTERS[1:variable]生成动态列名,只要variable是整数就行。比如先算出数据里最长的字符串能分成多少段,再动态生成对应列名:
# 计算最长分割段数:下划线数+1 max_segments <- max(str_count(test_data$category, "_")) + 1 # 用动态列名分割 test_data %>% separate(category, into = LETTERS[1:max_segments], sep = "_", fill = "right")
如果一定要用extract,也可以动态生成正则:
max_segments <- max(str_count(test_data$category, "_")) + 1 # 拼接动态正则 dynamic_regex <- paste0("(.+)", paste(rep("(?:_(.+))?", max_segments - 1), collapse = "")) test_data %>% extract(category, LETTERS[1:max_segments], dynamic_regex)
内容的提问来源于stack exchange,提问作者anderwyang
相关产品推荐
相关产品推荐

