Обновите значения столбца случайным образом на основе значения в другом столбце в R - PullRequest
0 голосов
/ 22 марта 2020

Я хочу добавить новый столбец SubCategory со значениями, заполненными случайным образом на основе значения столбца Category. Вот подробности:

Sub_Hair = c("Shampoo", "Conditioner", "Gel", "HairOil", "Dye")
Sub_Beauty = c("Face", "Eye", "Lips")
Sub_Nail= c("NailPolish", "NailPolishRemover", "NailArtKit", "ManiPadiKit")
Sub_Others = c("Electric", "NonElectric")

> product_data_1[1:10, c("Pcode", "Category", "MRP")]
    Pcode Category    MRP
1  16156L   Beauty  $8.88
2  16162M   Others $21.27
3  16168M   Others  $2.98
4  16169E     Nail $26.64
5  16207A     Hair  $6.38
6  17012B   Beauty $33.03
7  17012C   Beauty $20.58
8  17012F   Beauty $36.29
9  17091A     Nail $20.55
10 17107D     Nail $28.20

Я пытаюсь код ниже. Однако строки обновляются только с одной подкатегорией для каждой категории. Например, во всех строках с категорией «Красота» подкатегория «Глаз» вместо значений, случайно выбранных из «Лицо, Глаз и Губы». Вот код и вывод:

product_data_1 = within(product_data_1, SubCategory[Category == "Beauty"] <- sample(Sub_Beauty, 1))
product_data_1 = within(product_data_1, SubCategory[Category == "Hair"] <- sample(Sub_Hair, 1))
product_data_1 = within(product_data_1, SubCategory[Category == "Nail"] <- sample(Sub_Nail, 1))
product_data_1 = within(product_data_1, SubCategory[Category == "Others"] <- sample(Sub_Others, 1))

> product_data_1[1:10, c("Pcode", "Category", "MRP", "SubCategory")]
    Pcode Category    MRP SubCategory
1  16156L   Beauty  $8.88         Eye
2  16162M   Others $21.27    Electric
3  16168M   Others  $2.98    Electric
4  16169E     Nail $26.64  NailPolish
5  16207A     Hair  $6.38         Gel
6  17012B   Beauty $33.03         Eye
7  17012C   Beauty $20.58         Eye
8  17012F   Beauty $36.29         Eye
9  17091A     Nail $20.55  NailPolish
10 17107D     Nail $28.20  NailPolish

Ответы [ 2 ]

1 голос
/ 22 марта 2020

Поместите значения вашей подкатегории в список, как subcat_list <- list(Hair = Hair, Beauty = Beauty, Nail = Nail, Others = Others). Затем вы можете использовать product_data_1$Category для нарезки subcat_list и sapply для вызова sample для каждого элемента результирующего списка векторов:

set.seed(323)
product_data_1$SubCategory <- sapply(subcat_list[product_data_1$Category], sample, 1)

Вы также можете попробовать немного другой подход с dplyr + purrr:

library(tidyverse)
product_data_1 %>% 
    mutate(SubCategory = map_chr(Category, ~ sample(subcat_list[[.]], 1)))

Пример вывода:

    Pcode Category    MRP SubCategory
1  16156L   Beauty  $8.88         Eye
2  16162M   Others $21.27    Electric
3  16168M   Others  $2.98    Electric
4  16169E     Nail $26.64  NailPolish
5  16207A     Hair  $6.38         Gel
6  17012B   Beauty $33.03         Eye
7  17012C   Beauty $20.58        Lips
8  17012F   Beauty $36.29        Face
9  17091A     Nail $20.55 ManiPadiKit
10 17107D     Nail $28.20  NailArtKit
1 голос
/ 22 марта 2020

Вот базовое решение R. Он использует стратегию разделения / применения / объединения, описанную в этой статье JSS Хэдли Уикхэма.

Я помещу Sub_* векторов в список, Sub_list. Будьте осторожны, split упорядочит результат по Category, поэтому в списке Sub_list также должны быть векторы в порядке.

Sub_list <- list(Sub_Beauty, Sub_Hair, Sub_Nail, Sub_Others)
sp <- split(product_data_1, product_data_1$Category)

set.seed(1234)
sp <- lapply(seq_along(sp), function(i){
  sp[[i]]$SubCategory <- sample(Sub_list[[i]], nrow(sp[[i]]), replace = TRUE)
  sp[[i]]
})
result <- do.call(rbind, sp)
result <- result[order(as.integer(row.names(result))), ]
result
#    Pcode Category    MRP       SubCategory
#1  16156L   Beauty  $8.88               Eye
#2  16162M   Others $21.27       NonElectric
#3  16168M   Others  $2.98       NonElectric
#4  16169E     Nail $26.64        NailPolish
#5  16207A     Hair  $6.38           Shampoo
#6  17012B   Beauty $33.03               Eye
#7  17012C   Beauty $20.58              Face
#8  17012F   Beauty $36.29              Lips
#9  17091A     Nail $20.55 NailPolishRemover
#10 17107D     Nail $28.20       ManiPadiKit

Окончательная очистка.

rm(Sub_list)

Данные

product_data_1 <- read.table(text = "
    Pcode Category    MRP
1  16156L   Beauty  $8.88
2  16162M   Others $21.27
3  16168M   Others  $2.98
4  16169E     Nail $26.64
5  16207A     Hair  $6.38
6  17012B   Beauty $33.03
7  17012C   Beauty $20.58
8  17012F   Beauty $36.29
9  17091A     Nail $20.55
10 17107D     Nail $28.20
", header = TRUE)
...