R:在每个组内以及整个数据框内找到相对权重

时间:2016-11-01 03:14:19

标签: r dplyr frequency tidyverse

我的数据框在每行中都有一个值,其中包含两个其他变量。

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 个答案:

答案 0 :(得分:2)

原始答案 - 基于原始问题编号

一些额外的行应该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