2016-11-01 3 views
1

Mein Datenrahmen hat einen Wert in jeder Zeile, der zwei andere Variablen enthält.R: Finden Sie das relative Gewicht innerhalb jeder Gruppe und innerhalb des gesamten Datenrahmens

library(tidyverse) 
df <- data_frame(car=c('A','A','A','B','B'), style=c('aa','bb','aa','aa','cc'), value=c(3,2,5,4,16)) 

car style value 
A  aa  3 
A  bb  2 
A  aa  5 
B  aa  4 
B  cc  16 

Wie für jeden Stil in jeder Fahrzeuggruppe, und das relative Gewicht das relative Gewicht für jeden Stil finden über alle Daten? Hier ist die gewünschte Ausgabe (# Kommentare auf der rechten Seite nicht benötigt, aber hier aus Gründen der Übersichtlichkeit zeigt die Gesamtgewicht Berechnungen hinzugefügt):

car style value style_for_car style_total  # total value count is 30 
A  aa  3   0.80   0.40   # (3+5+4)/30 = 0.40 
A  bb  2   0.20   0.067  # 2/30 = 0.067    
A  aa  5   0.80   0.40   
B  aa  4   0.20   0.40 
B  cc  16   0.80   0.533 

Mein Versuch, unten nur das Gesamtgewicht bei der Berechnung erfolgreich ist. Wie die gewünschte Ausgabe innerhalb der gleichen dplyr Pipeline erhalten:

df %>% 
    group_by(style) %>% 
    mutate(style_total = sum(value)/sum(.$value)) 

    car style value style_total 
     A aa  3  0.4000 
     A bb  2  0.0667 
     A aa  5  0.4000 
     B aa  4  0.4000 
     B cc 16  0.5333 
+1

Hacky, aber so etwas wie 'df%>% group_by (Stil, Auto)%>% mutiert (style_for_car = Summe (Wert)/sum (. $ value [. $ car == auto]))%>% group_by (style)%>% muate (style_total = summe (wert)/summe (. $ value)) ', vielleicht – alistaire

+0

Kannst du dein reparieren? Beispiel? Sie haben '6' in der 5. Reihe in der Konstruktion von' df', dann '16' in der Ausgabe. – thelatemail

+0

Danke @thelatemail! Erledigt. – Irakli

Antwort

2

ORIGINAL Antwort- basierend auf Original Frage Zahlen

Ein paar zusätzliche Zeilen tun sollten, dass group_by(car) und mutate()-style_for_car zu berechnen ...

df %>% 
    group_by(car) %>% 
    mutate(style_for_car = value/sum(value)) %>% 
    group_by(style) %>% 
    mutate(style_total = sum(value)/sum(.$value)) 

#> Source: local data frame [5 x 5] 
#> Groups: style [3] 
#> 
#>  car style value style_for_car style_total 
#> <chr> <chr> <dbl>   <dbl>  <dbl> 
#> 1  A aa  3   0.3 0.40000000 
#> 2  A bb  2   0.2 0.06666667 
#> 3  A aa  5   0.5 0.40000000 
#> 4  B aa  4   0.2 0.40000000 
#> 5  B cc 16   0.8 0.53333333 

aKTUALISIERT ANTWORT - auf der Grundlage aktualisierter Frage Zahlen und Kommentar re .$

@alistaire eine nette Single-Pipe-Lösung in den Kommentaren. Um hinzuzufügen, würde ich dazu neigen, separate Datenrahmen mit relevanten Informationen zu erstellen, und sie dann mit dem ursprünglichen Datenrahmen zu verbinden. Dies hält den Code ein wenig lesbarer (zumindest für mich). Hier ist, wie ich es gehen würde (was auch von .$ entledigt):

# Create values for style_for_cars 
df_cars <- df %>% 
      group_by(car, style) %>% 
      summarise(value = sum(value)) %>% 
      group_by(car) %>% 
      mutate(style_for_car = value/sum(value)) %>% 
      select(-value) 
df_cars 
#> Source: local data frame [4 x 3] 
#> Groups: car [2] 
#> 
#>  car style style_for_car 
#> <chr> <chr>   <dbl> 
#> 1  A aa   0.8 
#> 2  A bb   0.2 
#> 3  B aa   0.2 
#> 4  B cc   0.8 

# Create values for style_total 
df_total <- df %>% 
       group_by(style) %>% 
       summarise(value = sum(value)) %>% 
       mutate(style_total = value/sum(value)) %>% 
       select(-value) 
df_total 
#> # A tibble: 3 × 2 
#> style style_total 
#> <chr>  <dbl> 
#> 1 aa 0.40000000 
#> 2 bb 0.06666667 
#> 3 cc 0.53333333 

# Join results 
df %>% 
    left_join(df_cars) %>% 
    left_join(df_total) 
#> Joining, by = c("car", "style") 
#> Joining, by = "style" 
#> # A tibble: 5 × 5 
#>  car style value style_for_car style_total 
#> <chr> <chr> <dbl>   <dbl>  <dbl> 
#> 1  A aa  3   0.8 0.40000000 
#> 2  A bb  2   0.2 0.06666667 
#> 3  A aa  5   0.8 0.40000000 
#> 4  B aa  4   0.2 0.40000000 
#> 5  B cc 16   0.8 0.53333333 
+1

Es ist im Wesentlichen das gleiche in 'data.table' sprechen -' df [, style_total: = Summe (Wert)/Summe (df [, Wert]), von = Stil] [, style_car: = Wert/Summe (Wert), von = Auto] ' – thelatemail

+0

Wow, das macht es! Ich weiß, dass ich ursprünglich nicht so "ordyversy" Summe (. $ Wert) verwendet habe. Gibt es einen Weg, um $ loszuwerden? – Irakli

+0

@thelatemail Ich stimme deinen Kommentaren zu Gewichten zu und korrigiere sie erneut! Simon Jackons Lösung funktioniert für einzelne Gewichte, aber nicht für relative Gewichte innerhalb jeder Gruppe. – Irakli

Verwandte Themen