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

在tidyr::pivot_longer中提取字符串中间首个数字的正则问题

解决tidyr::pivot_longer的names_pattern正则分组错误问题

问题背景

需要提取drink_type_1_Day_7、drink_vol_1_Day_7这类字段名中间的首个数字(范围1-10),完成pivot_longer数据转换。此前无Day_7后缀时用(.*)(.*)实现,但传入\d+作为names_pattern参数时,出现错误提示:

regex should define 2 groups; 1 found

希望通过构建包含两组的正则表达式(组1存储数字前缀内容,组2存储目标数字)解决问题,测试代码如下:

library(tidyr)

study_id <- c(1,2,3,4,5,6)
drink_type_1_Day_7 <-c(1,2,3,1,2,3)
drink_vol_1_Day_7 <- c(100,500,1000,100,500,750)
drink_type_2_Day_7 <-c(NA,3,2,1,NA,3)
drink_vol_2_Day_7 <- c(NA,125,300,200,NA,500)

drink_df  <- data.frame(study_id,drink_type_1_Day_7,drink_vol_1_Day_7,drink_type_2_Day_7,drink_vol_2_Day_7) 

drink_df <- drink_df %>% mutate_at(c('drink_type_1_Day_7','drink_type_2_Day_7'), as.factor) 

drink_df_pivot <- drink_df %>%
  pivot_longer(cols = starts_with("drink"), 
               names_to = c(".value", "drink"),
               names_pattern = "         ") %>% 
  dplyr::group_by(study_id, drink_type) %>% 
  dplyr:: summarise(drink_vol = sum(na_if(drink_vol,0), na.rm = TRUE), .groups = "drop") %>% pivot_wider(names_from = drink_type, values_from = drink_vol, 
              names_prefix = "drink_vol_", values_fill = 0) %>% 
  ungroup() %>%
  select(-contains("NA"))

解决方案

错误原因是names_to = c(".value", "drink")指定了两个目标元素,因此names_pattern必须包含两个捕获组,分别对应这两个元素:

  • 第一个组对应.value:字段名中数字之前的部分(如drink_type、drink_vol),后续会作为转换后的列名
  • 第二个组对应drink:需要提取的1-10数字部分

针对你的字段格式,可使用以下正则表达式:

"(.*)_([1-9]|10)_Day_7"
  • (.*):捕获数字前的所有内容(直到最后一个下划线)
  • ([1-9]|10):精准匹配1-10的数字(单独的1-9,或完整的10)
  • _Day_7:匹配固定后缀,确保只处理目标字段

修改后的完整代码如下:

library(tidyr)
library(dplyr)

study_id <- c(1,2,3,4,5,6)
drink_type_1_Day_7 <-c(1,2,3,1,2,3)
drink_vol_1_Day_7 <- c(100,500,1000,100,500,750)
drink_type_2_Day_7 <-c(NA,3,2,1,NA,3)
drink_vol_2_Day_7 <- c(NA,125,300,200,NA,500)

drink_df  <- data.frame(study_id,drink_type_1_Day_7,drink_vol_1_Day_7,drink_type_2_Day_7,drink_vol_2_Day_7) 

drink_df <- drink_df %>% mutate_at(c('drink_type_1_Day_7','drink_type_2_Day_7'), as.factor) 

drink_df_pivot <- drink_df %>%
  pivot_longer(cols = starts_with("drink"), 
               names_to = c(".value", "drink"),
               names_pattern = "(.*)_([1-9]|10)_Day_7") %>% 
  group_by(study_id, drink_type) %>% 
  summarise(drink_vol = sum(na_if(drink_vol,0), na.rm = TRUE), .groups = "drop") %>% 
  pivot_wider(names_from = drink_type, values_from = drink_vol, 
              names_prefix = "drink_vol_", values_fill = 0) %>% 
  ungroup() %>%
  select(-contains("NA"))

执行后即可正确提取数字并完成数据转换,解决正则分组不匹配的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:45:38