如何基于指定分组变量拆分含空格的DataFrame单列内容?
解决带空格食物名的分组提取问题
嗨,这个场景太常见了!我之前处理类似的非结构化字符串时也踩过同样的坑——直接按空格拆分肯定不行,因为食物名里有空格,但我们可以用正则表达式的捕获组+正向预查来精准匹配分组变量和对应的食物名,完全不用手动处理。
先把你的数据整理成标准的DataFrame(你原来的rbind得到的是矩阵,转成data.frame更方便后续处理):
library(stringr) library(dplyr) library(tidyr) # 构造你的数据 foo1 <- paste('FRUIT', 'Apple', 'PROTEIN', 'Chicken', 'STARCH', 'Banana Bread', 'FRUIT', 'Strawberry') foo2 <- paste('PROTEIN', 'Pork', 'FAT', 'Butter', 'FRUIT', 'Banana', 'STARCH', 'Spaghetti') foo3 <- paste('FRUIT', 'Strawberry', 'PROTEIN', 'Lean Steak', 'FRUIT', 'Strawberry', 'STARCH', 'Potato') df <- data.frame(text = c(foo1, foo2, foo3), stringsAsFactors = FALSE)
接下来是核心解决方案:用正则表达式匹配每个分组变量(FRUIT/PROTEIN/STARCH/FAT)以及它后面直到下一个分组变量(或字符串结尾)的食物名,然后拆分整理成整洁的格式:
df_clean <- df %>% # 提取所有「分组变量 + 食物名」的片段 mutate(matches = str_extract_all(text, "(FRUIT|PROTEIN|STARCH|FAT)\\s+(.*?)(?=\\s+(FRUIT|PROTEIN|STARCH|FAT)|$)")) %>% # 把列表列展开成单行一条记录 unnest(matches) %>% # 拆分分组和食物名,extra="merge"确保带空格的食物名不被拆分 separate(matches, into = c("group", "food"), sep = "\\s+", extra = "merge")
正则表达式解释
这里的正则(FRUIT|PROTEIN|STARCH|FAT)\\s+(.*?)(?=\\s+(FRUIT|PROTEIN|STARCH|FAT)|$)是关键:
(FRUIT|PROTEIN|STARCH|FAT):精准匹配你的4个分组变量,作为第一个捕获组\\s+:匹配分组变量和食物名之间的一个或多个空格(.*?):非贪婪匹配后面的所有内容(也就是食物名,直到遇到下一个分组变量才停止)(?=\\s+(FRUIT|PROTEIN|STARCH|FAT)|$):正向预查,确保后面要么是另一个分组变量,要么是字符串结尾,避免把下一个分组的内容误算到当前食物名里
运行完代码后,df_clean就会是这样的整洁格式:
| group | food |
|---|---|
| FRUIT | Apple |
| PROTEIN | Chicken |
| STARCH | Banana Bread |
| FRUIT | Strawberry |
| PROTEIN | Pork |
| FAT | Butter |
| ... | ... |
这个方法完全自动化,不管你的500+条数据里有多少带空格的食物名,都能准确提取,不用手动映射!
内容的提问来源于stack exchange,提问作者CoolGuyHasChillDay
相关产品推荐
相关产品推荐

