首页 > 解决方案 > R中的数据框操作:在数字和字母之间以单个顺序分隔多个项目

问题描述

我有一个庞大的销售数据数据框,其中包含客户数据和订单信息。不幸的是,对于每个客户条目,每个客户出售的物品都被拼成一个长串,即鸡蛋 x 2 @ 6 美元面包 x 2 @ 5 美元鸡肉 x 3 @ 15 美元。我一直在搞乱 dplyr 和 regex 命令,但它只是创建了新列。

newdf <- df %>%
         separate(V3, 
              into = c("Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7"), 
          sep = "(?=[0-9])(?<=[A-Za-z])")

输入

V1 V2 V3
顾客 购买的物品 项目
3 鸡蛋 x 2 @ $6 面包 x 2 @ $5 鸡肉 x 3 @ $15
鲍勃 1 桌子 x 1 @ $75
标记 7 苹果 x 2 @ $7 面包 x 1 @ $7 鸡肉 x 3 @ $15 鸡蛋 x 2 @ $6 面包 x 2 @ $5 鸡肉 x 3 @ $15 种子 x 3 @ $2

期望的输出

V1 V2 V3 V4 V5 V6 V7 V8 V9
顾客 购买的物品 项目 1 第 2 项 第 3 项 第 4 项 第 5 项 第 6 项 第 7 项
3 鸡蛋 x 2 @ $6 面包 x 2 @ $5 鸡肉 x 3 @ $15
鲍勃 1 桌子 x 1 @ $75
标记 7 苹果 x 2 @ $7 面包 x 1 @ $7 鸡肉 x 3 @ $15 鸡蛋 x 2 @ $6 面包 x 2 @ $5 鸡肉 x 3 @ $15 种子 x 3 @ $2

标签: rregexstringdplyr

解决方案


这是您可以使用的另一种方式。应该注意的是,我使用了一个正则表达式模式来匹配您想要的子字符串,但是因为它也可以匹配我使用?运算符的 who 字符串使其变得懒惰,以便在它匹配最短的可能字符串之后它再次寻找另一个:

library(dplyr)
library(tidyr)

df %>%
  mutate(output = regmatches(Items, gregexpr("[A-Z].*?\\$\\d+", Items, perl = TRUE))) %>%
  unnest_wider(output) %>% 
  setNames(gsub("(\\.){3}(\\d)", "Item\\2", names(.)))

# A tibble: 3 x 10
  Customer Items.Purchased Items              Item1   Item2   Item3  Item4  Item5  Item6  Item7 
  <chr>              <int> <chr>              <chr>   <chr>   <chr>  <chr>  <chr>  <chr>  <chr> 
1 Jane                   3 Eggs x 2 @ $6Brea~ Eggs x~ Bread ~ Chick~ NA     NA     NA     NA    
2 Bob                    1 Table x 1 @ $75    Table ~ NA      NA     NA     NA     NA     NA    
3 Mark                   7 Apples x 2 @ $7Br~ Apples~ Bread ~ Chick~ Eggs ~ Bread~ Chick~ Seeds~

推荐阅读