Как мне изменить набор вариантов для каждой строки в R?

#r #dplyr

#r #dplyr

Вопрос:

У меня есть следующие данные:

 | parent_sku |    sku   | stock_status | regular_price | tax_class | 
|:----------:|:--------:|:------------:|:-------------:|:---------:|
| ABBBOA01   | ABBBOA01 | instock      | 1299          | parent    | 
| ABBBOA03   | ABBBOA03 | instock      | 1299          | parent    | 
| ABBBOA02   | ABBBOA02 | instock      | 1299          | parent    | 
| ABBBOA04   | ABBBOA04 | instock      | 1299          | parent    | 
 

Я хотел бы изменить четыре варианта для каждого parent_sku , M , L , XL и XXL . Например, приведенные выше данные должны быть преобразованы в:

 | parent_sku |    sku   | stock_status | regular_price | tax_class |    attribute_size   |
|:----------:|:--------:|:------------:|:-------------:|:---------:|:-------------------:|
| ABBBOA01   | ABBBOA01 | instock      | 1299          | parent    | M                   |
| ABBBOA01   | ABBBOA01 | instock      | 1299          | parent    | X                   |
| ABBBOA01   | ABBBOA01 | instock      | 1299          | parent    | XL                  |
| ABBBOA01   | ABBBOA01 | instock      | 1299          | parent    | XXL                 |
| ABBBOA03   | ABBBOA03 | instock      | 1299          | parent    | M                   |
| ABBBOA03   | ABBBOA03 | instock      | 1299          | parent    | L                   |
| ABBBOA03   | ABBBOA03 | instock      | 1299          | parent    | XL                  |
...
and so on
 

Я пытался сделать что-то вроде этого:

 data %>% group_by(parent_sku) %>%
  rowwise() %>% 
  mutate(attribute_size = 'M') %>%
  mutate(attribute_size = 'L') %>%
  mutate(attribute_size = 'XL') %>%
  mutate(attribute_size = 'XXL')
 

Но это не работает.

Ответ №1:

Один из способов сделать это — добавить все размеры в виде столбца списка, содержащего вектор размеров. Затем используйте unnest_longer() , чтобы разложить его по строкам.

 library(dplyr)
library(tidyr)

# this should work with all the columns
data <- tibble(parent_sku = paste0("ABBBOA0", 1:4),
               stock_status = rep("instock", 4))

sizes <- c("M", "L", "XL", "XXL")

data %>% 
  mutate(attribute_size = list(sizes)) %>% 
  unnest_longer(attribute_size)
 

Что дает вам расширение…

 # A tibble: 16 x 3
   parent_sku stock_status attribute_size
   <chr>      <chr>        <chr>         
 1 ABBBOA01   instock      M             
 2 ABBBOA01   instock      L             
 3 ABBBOA01   instock      XL            
 4 ABBBOA01   instock      XXL           
 5 ABBBOA02   instock      M             
 6 ABBBOA02   instock      L             
 7 ABBBOA02   instock      XL            
 8 ABBBOA02   instock      XXL           
 9 ABBBOA03   instock      M             
10 ABBBOA03   instock      L             
11 ABBBOA03   instock      XL            
12 ABBBOA03   instock      XXL           
13 ABBBOA04   instock      M             
14 ABBBOA04   instock      L             
15 ABBBOA04   instock      XL            
16 ABBBOA04   instock      XXL  
 

Комментарии:

1. Спасибо за ваш ответ! Как это будет работать для остальной части строки? Кажется, что я указываю paste0("ABBBOA0", 1:4) , но реальный набор данных имеет около 200 уникальных parent_sku , которые не обязательно следуют шаблону?

2. Он должен просто брать каждую строку и копировать ее. Так что просто используйте свои данные вместо образцов данных, которые я сгенерировал. Все, что я там делал, это ввод ваших данных, чтобы быстро показать пример.

3. Извините, я этого там не видел. Большое вам спасибо, это работает блестяще!!

Ответ №2:

вот data.table решение

 library( data.table )
DT <- fread("
parent_sku |    sku   | stock_status | regular_price | tax_class 
ABBBOA01   | ABBBOA01 | instock      | 1299          | parent    
ABBBOA03   | ABBBOA03 | instock      | 1299          | parent    
ABBBOA02   | ABBBOA02 | instock      | 1299          | parent    
ABBBOA04   | ABBBOA04 | instock      | 1299          | parent   ",
            sep = "|" )

sizes <- c("M", "L", "XL", "XXL")

DT[ CJ( DT$parent_sku, sizes, unique = TRUE ), on = .(parent_sku = V1) ]

#     parent_sku      sku stock_status regular_price tax_class sizes
#  1:   ABBBOA01 ABBBOA01      instock          1299    parent     L
#  2:   ABBBOA01 ABBBOA01      instock          1299    parent     M
#  3:   ABBBOA01 ABBBOA01      instock          1299    parent    XL
#  4:   ABBBOA01 ABBBOA01      instock          1299    parent   XXL
#  5:   ABBBOA02 ABBBOA02      instock          1299    parent     L
#  6:   ABBBOA02 ABBBOA02      instock          1299    parent     M
#  7:   ABBBOA02 ABBBOA02      instock          1299    parent    XL
#  8:   ABBBOA02 ABBBOA02      instock          1299    parent   XXL
#  9:   ABBBOA03 ABBBOA03      instock          1299    parent     L
# 10:   ABBBOA03 ABBBOA03      instock          1299    parent     M
# 11:   ABBBOA03 ABBBOA03      instock          1299    parent    XL
# 12:   ABBBOA03 ABBBOA03      instock          1299    parent   XXL
# 13:   ABBBOA04 ABBBOA04      instock          1299    parent     L
# 14:   ABBBOA04 ABBBOA04      instock          1299    parent     M
# 15:   ABBBOA04 ABBBOA04      instock          1299    parent    XL
# 16:   ABBBOA04 ABBBOA04      instock          1299    parent   XXL