R: условная сумма по различным кадрам данных с Базой R - PullRequest
0 голосов
/ 10 октября 2019

Я ищу решение в базе R.

У меня есть два следующих кадра данных df1 и `df2:

Subcategory <- c("BODY", "FACE", "FACE")
Brand <- c("NIVEA", "CD", "Valdini")
Product <- c("NIV_A", "CD_1", "Valdin")
Sales_Month <- c("01-18", "02-18", "02-18")
fwd1 <- c("02-18", "03-18", "03-18")
fwd2 <- c("03-18", "04-18", "04-18")
df1 <- data.frame(Subcategory, Brand, Product, Sales_Month, fwd1, fwd2)
df1

  Subcategory   Brand Product Sales_Month  fwd1  fwd2
1        BODY   NIVEA   NIV_A       01-18 02-18 03-18
2        FACE      CD    CD_1       02-18 03-18 04-18
3        FACE Valdini  Valdin       02-18 03-18 04-18

и

SubCat <- rep(c("BODY", "FACE"), times = c(12,20))
Brand2 <- rep(c("NIVEA", "BEBE", "CD", "Valdini", "NIVEA"), times = c(8,4,12,4,4))
Product2 <- rep(c("NIV_A", "NIV_B", "BEB_1", "CD_1", "CD_2", "CD_3","Vald","NIV_1"), each = 4)
SalesMonth2 <- rep(c("01-18", "02-18", "03-18", "04-18"), times = 8)
Sales2 <- c(300,400,30,20,400,200,300,1000,300,200,400,500,20,30,1,2,3,50,600,70,80,90,100,10,300, 1000,70,30,20,10,18,20)
Sum_Prod <- c(0,430,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0)
df2 <- data.frame(SubCat, Brand2, Product2, SalesMonth2, Sales2, Sum_Prod)
df2

 SubCat  Brand2 Product2 SalesMonth2 Sales2 Sum_Prod
1    BODY   NIVEA    NIV_A       01-18    300        0
2    BODY   NIVEA    NIV_A       02-18    400      430
3    BODY   NIVEA    NIV_A       03-18     30        0
4    BODY   NIVEA    NIV_A       04-18     20        0
5    BODY   NIVEA    NIV_B       01-18    400        0
6    BODY   NIVEA    NIV_B       02-18    200        0
7    BODY   NIVEA    NIV_B       03-18    300        0
8    BODY   NIVEA    NIV_B       04-18   1000        0
9    BODY    BEBE    BEB_1       01-18    300        0
10   BODY    BEBE    BEB_1       02-18    200        0
11   BODY    BEBE    BEB_1       03-18    400        0
12   BODY    BEBE    BEB_1       04-18    500        0
13   FACE      CD     CD_1       01-18     20        0
14   FACE      CD     CD_1       02-18     30        0
15   FACE      CD     CD_1       03-18      1        3
16   FACE      CD     CD_1       04-18      2        0
17   FACE      CD     CD_2       01-18      3        0
18   FACE      CD     CD_2       02-18     50        0
19   FACE      CD     CD_2       03-18    600        0
20   FACE      CD     CD_2       04-18     70        0
21   FACE      CD     CD_3       01-18     80        0
22   FACE      CD     CD_3       02-18     90        0
23   FACE      CD     CD_3       03-18    100        0
24   FACE      CD     CD_3       04-18     10        0
25   FACE Valdini     Vald       01-18    300        0
26   FACE Valdini     Vald       02-18   1000        0
27   FACE Valdini     Vald       03-18     70      100
28   FACE Valdini     Vald       04-18     30        0
29   FACE   NIVEA    NIV_1       01-18     20        0
30   FACE   NIVEA    NIV_1       02-18     10        0
31   FACE   NIVEA    NIV_1       03-18     18        0
32   FACE   NIVEA    NIV_1       04-18     20        0

Мне нужно выполнить условную сумму для этих двух фреймов данных. Переменная Sum_Prod в df2 представляет собой сумму продаж Продуктов, указанных в df1 за месяцы fwd1 + fwd2. Например: In df1, fwd1 для NIV_A - 02-18, fwd2 для NIV_A - 03-18. В df2 соответствующие продажи этих месяцев составляют 400 и 30 соответственно. Поэтому Sum_Prod для NIV_A равно 430.

Теперь мне нужно вычислить другую переменную Sum_Brand, представляющую сумму произведений в df2, которая:

  1. находится вта же подкатегория, что и в df1
  2. В пределах той же марки, что и в df1
  3. Для месяцев, соответствующих fwd1 и fwd2, как показано в df1
  4. Исключая продукты, которые уже суммированы в Prod_Sum в df2

Результат должен выглядеть примерно так:

   SubCat  Brand2 Product2 SalesMonth2 Sales2 Sum_Prod Sum_Brand
1    BODY   NIVEA    NIV_A       01-18    300        0       500
2    BODY   NIVEA    NIV_A       02-18    400      430       500
3    BODY   NIVEA    NIV_A       03-18     30        0       500
4    BODY   NIVEA    NIV_A       04-18     20        0       500
5    BODY   NIVEA    NIV_B       01-18    400        0       500
6    BODY   NIVEA    NIV_B       02-18    200        0       500
7    BODY   NIVEA    NIV_B       03-18    300        0       500
8    BODY   NIVEA    NIV_B       04-18   1000        0       500
9    BODY    BEBE    BEB_1       01-18    300        0         0
10   BODY    BEBE    BEB_1       02-18    200        0         0
11   BODY    BEBE    BEB_1       03-18    400        0         0
12   BODY    BEBE    BEB_1       04-18    500        0         0
13   FACE      CD     CD_1       01-18     20        0       780
14   FACE      CD     CD_1       02-18     30        0       780
15   FACE      CD     CD_1       03-18      1        3       780
16   FACE      CD     CD_1       04-18      2        0       780
17   FACE      CD     CD_2       01-18      3        0       780
18   FACE      CD     CD_2       02-18     50        0       780
19   FACE      CD     CD_2       03-18    600        0       780
20   FACE      CD     CD_2       04-18     70        0       780
21   FACE      CD     CD_3       01-18     80        0       780
22   FACE      CD     CD_3       02-18     90        0       780
23   FACE      CD     CD_3       03-18    100        0       780
24   FACE      CD     CD_3       04-18     10        0       780
25   FACE Valdini     Vald       01-18    300        0         0
26   FACE Valdini     Vald       02-18   1000        0         0
27   FACE Valdini     Vald       03-18     70      100         0
28   FACE Valdini     Vald       04-18     30        0         0
29   FACE   NIVEA    NIV_1       01-18     20        0         0
30   FACE   NIVEA    NIV_1       02-18     10        0         0
31   FACE   NIVEA    NIV_1       03-18     18        0         0
32   FACE   NIVEA    NIV_1       04-18     20        0         0

Снова идти сПример NIVEA: fwd1 - это 02-18, а fwd2 - это 03-18. Единственный продукт, который соответствует подкатегории 'BODY' и торговой марке 'NIVEA' в df2, это NIV_B. fwd1 and fwd2 `продажи за месяц составляют 200 и 300 соответственно. Следовательно, Sum_Brand - это 500 для NIVEA в категории «BODY».

Значения для Valdini могут быть «NA». Я совершенно не знаю, как подойти к этой проблеме.

Мне нужно решение в Base R.

Может кто-нибудь помочь, пожалуйста?

Best, Mariella

1 Ответ

0 голосов
/ 10 октября 2019

Может быть, следующее делает то, что вы хотите. По крайней мере, он воспроизводит ваш ожидаемый результат:

df1$Product  <- c("NIV_A", "CD_1", "Vald")

df2$SalesMonth2  <- as.character(df2$SalesMonth2)
df1$fwd1  <- as.character(df1$fwd1)
df1$fwd2  <- as.character(df1$fwd2)

df2$Sum_Prod <- 0
for(i in seq_len(nrow(df1))) {
    idx  <- interaction(df1[i,1:3]) == interaction(df2[1:3])
    idx2 <- df2$SalesMonth2[idx] %in% df1[i,c("fwd1", "fwd2")]
    if(any(idx) && any(idx2)) {
        tt <- sum(df2$Sales2[idx][idx2])
        df2$Sum_Prod[idx][which(idx2)[1]]  <- tt
    }
}

df2$Sum_Brand <- 0
for(i in seq_len(nrow(df1))) {
    idx  <- interaction(df1[i,1:2]) == interaction(df2[1:2])
    idx2 <- df2$SalesMonth2[idx] %in% df1[i,c("fwd1", "fwd2")]
    if(any(idx) && any(idx2)) {
        tt <- sum(df2$Sales2[idx][idx2]) - sum(df2$Sum_Prod[idx])
        df2$Sum_Brand[idx]  <- tt
    }

}
df2
#   SubCat  Brand2 Product2 SalesMonth2 Sales2 Sum_Prod Sum_Brand
#1    BODY   NIVEA    NIV_A       01-18    300        0       500
#2    BODY   NIVEA    NIV_A       02-18    400      430       500
#3    BODY   NIVEA    NIV_A       03-18     30        0       500
#4    BODY   NIVEA    NIV_A       04-18     20        0       500
#5    BODY   NIVEA    NIV_B       01-18    400        0       500
#6    BODY   NIVEA    NIV_B       02-18    200        0       500
#7    BODY   NIVEA    NIV_B       03-18    300        0       500
#8    BODY   NIVEA    NIV_B       04-18   1000        0       500
#9    BODY    BEBE    BEB_1       01-18    300        0         0
#10   BODY    BEBE    BEB_1       02-18    200        0         0
#11   BODY    BEBE    BEB_1       03-18    400        0         0
#12   BODY    BEBE    BEB_1       04-18    500        0         0
#13   FACE      CD     CD_1       01-18     20        0       780
#14   FACE      CD     CD_1       02-18     30        0       780
#15   FACE      CD     CD_1       03-18      1        3       780
#16   FACE      CD     CD_1       04-18      2        0       780
#17   FACE      CD     CD_2       01-18      3        0       780
#18   FACE      CD     CD_2       02-18     50        0       780
#19   FACE      CD     CD_2       03-18    600        0       780
#20   FACE      CD     CD_2       04-18     70        0       780
#21   FACE      CD     CD_3       01-18     80        0       780
#22   FACE      CD     CD_3       02-18     90        0       780
#23   FACE      CD     CD_3       03-18    100        0       780
#24   FACE      CD     CD_3       04-18     10        0       780
#25   FACE Valdini     Vald       01-18    300        0         0
#26   FACE Valdini     Vald       02-18   1000        0         0
#27   FACE Valdini     Vald       03-18     70      100         0
#28   FACE Valdini     Vald       04-18     30        0         0
#29   FACE   NIVEA    NIV_1       01-18     20        0         0
#30   FACE   NIVEA    NIV_1       02-18     10        0         0
#31   FACE   NIVEA    NIV_1       03-18     18        0         0
#32   FACE   NIVEA    NIV_1       04-18     20        0         0
...