Výpočet sloupců v procentech na základě jiných sloupců pro jednotlivé kategorie v R

0

Otázka

Jsem začátečník s R a potřebují pomoc s úkolem. Výstup figuríny dataset s dput (skutečný soubor je opravdu velký):

structure(list(CODE = c(453, 463, 476, 
798, 885, 582, 626, 663, 457, 408
), CATEGORY = c("CIG", "BET", "CIG", "CIG", "ARI", "CRR", "ARI", "CIG", 
"CIG", "BET"), AMOUNT = c(22, 5, 6, 52, 16, 11, 6, 70, 208, 5), 
    PRICE = c(5.56, 8.29, 3.89, 3.8, 4.05, 3.99, 3.55, 7.69, 6.75, 
    5.2), BRAND = c("ROTHMANS", "ALLINO", "MARLBORO", "ROTHMANS", "AURIELO", 
    "SOLINOS", "CHLEBLO", "MARLBORO", "LD", "SOLINOS"
    )), row.names = c(NA, -10L), class = c("tbl_df", 
"tbl", "data.frame"))

Co je třeba udělat: sloupec, který bude zobrazovat podíl každé ZNAČKY v procentech by měla být přidána. První, co jsem udělat, je vytvořit nový sloupec "HODNOTA" tímto způsobem:

df$VALUE <- with(df, AMOUNT*PRICE)

Teď sloupci PODÍL musí být vytvořeny takovým způsobem,: součet hodnot (sloupec HODNOTA) z konkrétní značky v určité kategorii vydělí součtem hodnot z celé kategorie. Například, "ROTHMANS" je v kategorii CIG, součet hodnot je 319.92, součtu pro celou CIG kategorie je 2285,56, takže PODÍL=14%. A to by měla být vypočtena v každém případě. Myslím, že knihovna dplyr může být vhodné, ale nemůžu najít řešení.

calculated-columns dataframe dplyr r
2021-10-27 13:19:23
3

Nejlepší odpověď

1

Můžete nejprve sum na BRAND hodnotu a získat podíl pro každého CATEGORY.

library(dplyr)

df %>%
  group_by(CATEGORY, BRAND) %>%
  summarise(VALUE = sum(VALUE)) %>%
  mutate(SHARE = prop.table(VALUE) * 100) %>%
  ungroup

#  CATEGORY BRAND     VALUE SHARE
#  <chr>    <chr>     <dbl> <dbl>
#1 ARI      AURIELO    64.8  75.3
#2 ARI      CHLEBLO    21.3  24.7
#3 BET      ALLINO     41.4  61.5
#4 BET      SOLINOS    26    38.5
#5 CIG      LD       1404    61.4
#6 CIG      MARLBORO  562.   24.6
#7 CIG      ROTHMANS  320.   14.0
#8 CRR      SOLINOS    43.9 100  
2021-10-27 13:24:05

Vypadá to, že nový sloupec je vypočítaná dobře, ale proč ostatní sloupce (KÓD, MNOŽSTVÍ, CENA) zmizí? Ve skutečnosti, oni by měli být v závěrečné sadě. @RonakShah
Bambeil

Jistě, můžete přidat %>% left_join(df, by = c("CATEGORY", "BRAND")) dostat je zpět, ale na vědomí, že od své původní df má duplicitní řádky pro každou značku konečný výstup by to taky.
Ronak Shah
1

A data.table řešení by mohlo být:

library(data.table)

res <- setDT(df)[,'.'(VALUE = sum(VALUE)), by = list(CATEGORY,BRAND)
               ][,':='(SHARE = round(VALUE/sum(VALUE)*100,2)), by = list(CATEGORY)]

res
  CATEGORY    BRAND   VALUE  SHARE
1:      CIG ROTHMANS  319.92  14.00
2:      BET   ALLINO   41.45  61.45
3:      CIG MARLBORO  561.64  24.57
4:      ARI  AURIELO   64.80  75.26
5:      CRR  SOLINOS   43.89 100.00
6:      ARI  CHLEBLO   21.30  24.74
7:      CIG       LD 1404.00  61.43
8:      BET  SOLINOS   26.00  38.55

EDIT

Zachovat původní hodnoty, by mohl být tento:

res <- setDT(df)[,'.'(VALUE = sum(VALUE)), by = list(CATEGORY,BRAND)
               ][,':='(SHARE = round(VALUE/sum(VALUE)*100,2)), by = list(CATEGORY)
               ][setDT(df), on = c('BRAND','CATEGORY')
               ][,-('i.VALUE')]
res

    CATEGORY    BRAND   VALUE  SHARE CODE AMOUNT PRICE
 1:      CIG ROTHMANS  319.92  14.00  453     22  5.56
 2:      BET   ALLINO   41.45  61.45  463      5  8.29
 3:      CIG MARLBORO  561.64  24.57  476      6  3.89
 4:      CIG ROTHMANS  319.92  14.00  798     52  3.80
 5:      ARI  AURIELO   64.80  75.26  885     16  4.05
 6:      CRR  SOLINOS   43.89 100.00  582     11  3.99
 7:      ARI  CHLEBLO   21.30  24.74  626      6  3.55
 8:      CIG MARLBORO  561.64  24.57  663     70  7.69
 9:      CIG       LD 1404.00  61.43  457    208  6.75
10:      BET  SOLINOS   26.00  38.55  408      5  5.20
2021-10-27 14:00:19

Vypadá to, že nový sloupec je vypočítaná dobře, ale proč ostatní sloupce (KÓD, MNOŽSTVÍ, CENA) zmizí? Ve skutečnosti, oni by měli být v závěrečné sadě. @s__
Bambeil

Protože kód je seskupení a souhrn. V případě, že jste se k němu může připojit k původní df, aby si ty informace ale budete oklamat SHARE a VALUE výsledek (počítáno VALUE).
s__

@Bambeil viz edit pro vysvětlení.
s__
1

Můžeme použít base R

transform(aggregate(VALUE ~ CATEGORY + BRAND, df, sum), 
    SHARE = ave(VALUE, CATEGORY, FUN = proportions) * 100)
  CATEGORY    BRAND   VALUE     SHARE
1      BET   ALLINO   41.45  61.45293
2      ARI  AURIELO   64.80  75.26132
3      ARI  CHLEBLO   21.30  24.73868
4      CIG       LD 1404.00  61.42915
5      CIG MARLBORO  561.64  24.57341
6      CIG ROTHMANS  319.92  13.99744
7      BET  SOLINOS   26.00  38.54707
8      CRR  SOLINOS   43.89 100.00000
2021-10-27 13:37:37

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................