2016-11-01 13 views
1

В моей строке данных есть одно значение в каждой строке, содержащей две другие переменные.R: найти относительный вес внутри каждой группы и всего кадра данных

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 

Как найти относительный вес для каждого стиля в каждой группе автомобилей, а также относительный вес для каждого стиля над всеми данными? Вот желаемый результат (# комментариев на право не нужен, но добавил для ясности здесь показаны общие вычисления веса):

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 

Моя попытка только ниже преуспевает расчета общего веса. Как получить желаемый результат в пределах одного dplyr трубопровода:

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, но что-то вроде 'ДФ%>% group_by (стиль, автомобиль)%>% мутировать (style_for_car = сумма (стоимость)/sum (. $ value [. $ car == car]))%>% group_by (style)%>% mutate (style_total = sum (value)/sum (. $ value)) ', возможно – alistaire

+0

Можете ли вы исправить свои пример? У вас есть '6' в 5-й строке в построении' df', а затем '16' на выходе. – thelatemail

+0

Спасибо @thelatemail! Готово. – Irakli

ответ

2

ORIGINAL ответа- на основе оригинальных номеров вопрос

Несколько дополнительных линий должны сделать group_by(car) и mutate() вычислить style_for_car ...

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 

ОБНОВЛЕНО ОТВЕТ - на основе обновленных номеров вопрос и комментарий повторно .$

@alistaire положил хорошее однотрубное решение в комментариях. Чтобы добавить, я был бы склонен создавать отдельные кадры данных с соответствующей информацией, а затем присоединять их к исходному фрейму данных. Это приводит к тому, что код становится более читаемым (по крайней мере для меня). Вот как я бы об этом (который также избавляется от .$):

# 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

Это по сути то же самое в 'data.table' speak -' df [, style_total: = sum (value)/sum (df [, value]), by = style] [, style_car: = значение/сумма (значение), by = car] ' – thelatemail

+0

Вау, вот и все! Я знаю, что изначально я использовал не такую ​​«tidyversy» sum (. $ Value). Есть ли способ избавиться от $? – Irakli

+0

@thelatemail Я согласен с вашими комментариями о весах и исправил их! Решение Simon Jackon работает для отдельных весов, но не относительных весов внутри каждой группы. – Irakli

 Смежные вопросы

  • Нет связанных вопросов^_^