У меня есть фрейм данных с продуктом и количеством. Я хотел бы для каждого продукта добавить 3 строки с пропорциональным распределением в подпродуктах X1, X2, X3. Процент зависит от веса:
X1 = 0.19
X2 = 0.26
X3 = 0.55
Фрейм данных выглядит так:
df = data.frame(Product = c("A","B","C","D"), value = c(30,35,42,12))
Product Quantity
1 A 30
2 B 35
3 C 42
4 D 1
Таблица, которую я хотел бы построить в конце, должна выглядеть так:
Product Quantity
1 A 30.00
2 X1 5.70
3 X2 7.80
4 X3 16.50
5 B 35.00
6 X1 0.00
7 X2 9.10
8 X3 19.25
9 C 42.00
10 X1 0.00
11 X2 10.92
12 X3 23.10
13 D 12.00
14 X1 0.00
15 X2 3.12
16 X3 6.60
Есть ли способ R сделать это без использования цикла (на случай, если продуктов слишком много)?
Вы можете создать фрейм данных для информации о пропорциях и использовать crossing
для создания всех комбинаций строк с исходным df
.
library(dplyr)
ref <- data.frame(Product1 = c('X1', 'X2', 'X3'),
Quantity1 = c(0.19, 0.26, 0.55))
tidyr::crossing(ref, df) %>%
transmute(Product, Product1, value = Quantity1 * value) %>%
bind_rows(df) %>%
arrange(Product, !is.na(Product1)) %>%
mutate(Product = coalesce(Product1, Product)) %>%
select(-Product1)
# Product value
# <chr> <dbl>
# 1 A 30
# 2 X1 5.7
# 3 X2 7.8
# 4 X3 16.5
# 5 B 35
# 6 X1 6.65
# 7 X2 9.1
# 8 X3 19.2
# 9 C 42
#10 X1 7.98
#11 X2 10.9
#12 X3 23.1
#13 D 12
#14 X1 2.28
#15 X2 3.12
#16 X3 6.6
Я думаю, у вас загружен пакет MASS
вместе с dplyr
. Попробуйте вместо этого использовать dplyr::select
.
эй, я помещаю dplyr:: почти везде, где вызывается функция dplyr, и я получаю: Ошибка: аргумент 2 должен быть объектом factor
, а не вектором символов, точно в строке «мутировать». Вы случайно не преобразовывали df$Product?
У вас R < 4.0.0? При создании фрейма данных вам нужно добавить stringsAsFactors = FALSE
как при создании df
, так и при создании ref
, чтобы у вас были столбцы символов вместо факторов. df = data.frame(Product = c("A","B","C","D"), value = c(30,35,42,12), stringsAsFactors = FALSE)
и ref <- data.frame(Product1 = c('X1', 'X2', 'X3'), Quantity1 = c(0.19, 0.26, 0.55), stringsAsFactors = FALSE)
И это работает! :) Большое спасибо. мы получили там.
Привет Ронак, большое спасибо, я получаю следующую ошибку при тестировании вашего кода: Ошибка в выборе (., -Product1): неиспользуемый аргумент (-Product1) Кроме того: Предупреждающее сообщение: In
[<-.factor
(*tmp*
, i, value = 1 :4) : неверный уровень фактора, сгенерировано NA