如何在不使脚本太大的情况下一次计算多个百分比

how to calculate many percentages at once without making your script too big

mtcars 数据集包含带有化油器数量的变量“carb”。首先,我想知道有多少辆汽车有 1、2、3 等化油器。我使用了 dplyr 动词 count()。

library(dplyr)

df <- mtcars 

N <- df %>%
  count(carb)

这导致:

> N
  carb  n
1    1  7
2    2 10
3    3  3
4    4 10
5    6  1
6    8  1 

然后我想知道,有多少汽车有 1 个碳水化合物、2 个碳水化合物、 3 等有 4、6 或 8 个汽缸。

例如:我使用 filter() 找出 1 个碳水化合物和 4 个汽缸的汽车总数:

carb1cyl4 <- df %>%
  filter(carb == 1, cyl == 4) %>%
  count() %>%
  rename(carb1cyl4 = n)

这导致:

  carb1cyl4
1         5

我对 6 缸和 8 缸做了同样的操作,结果如下:


  carb1cyl6
1         2
  carb1cyl8
1         0

如果我对所有碳水化合物继续这样做,我可以做一些 _rows 和 _cols 绑定,然后使用 mutate(carbXcylX / N) 计算具有一定数量碳水化合物和圆柱体的汽车的百分比,所以基本上除以数量每个碳水化合物/汽缸组合的汽车数量乘以具有相应碳水化合物数量的汽车数量。

问题是,如果我继续这条路线,我的数据集要大得多,而且会花费很长时间,而且很容易出错。还有其他计算方法吗?

最终结果应该是这样的。

  carb  n  perc1cy4  perc1cy6 perc1cy8
1    1  7 0.7142857 0.2857143        0

提前致谢!

我可能会建议使用

之类的内容制作一个组大小列
count_df <- df %>% count(carb, cyl) %>% rename(n = group_size)

然后您可以将其内部连接到 table

inner_join(df, count_df, by = c("carb", "cyl")

然后用

计算百分比
mutate(perc = (n/group_size) * 100)

这可以做得更简洁,但这里是一个起点,使用 summarise

mtcars %>%
  group_by(carb) %>%
  summarise(n(),
            sum(cyl == 4),
            sum(cyl == 6),
            sum(cyl == 8),
            mean(cyl == 4),
            mean(cyl == 6),
            mean(cyl == 8))

#> # A tibble: 6 x 8
#>    carb `n()` `sum(cyl == 4)` `sum(cyl == 6)` `sum(cyl == 8)` `mean(cyl == 4)` `mean(cyl == 6)` `mean(cyl == 8)`
#>   <dbl> <int>           <int>           <int>           <int>            <dbl>            <dbl>            <dbl>
#> 1     1     7               5               2               0            0.714            0.286              0  
#> 2     2    10               6               0               4            0.6              0                  0.4
#> 3     3     3               0               0               3            0                0                  1  
#> 4     4    10               0               4               6            0                0.4                0.6
#> 5     6     1               0               1               0            0                1                  0  
#> 6     8     1               0               0               1            0                0                  1

使用table:

cbind(n = table(mtcars$carb),
      prop.table(with(mtcars, table(carb, cyl)), margin = 1))
#    n         4         6   8
# 1  7 0.7142857 0.2857143 0.0
# 2 10 0.6000000 0.0000000 0.4
# 3  3 0.0000000 0.0000000 1.0
# 4 10 0.0000000 0.4000000 0.6
# 6  1 0.0000000 1.0000000 0.0
# 8  1 0.0000000 0.0000000 1.0