我的数据框在每行中都有一个值,其中包含两个其他变量。
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
答案 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