dplyr::mutate() 将多行作为方程右侧函数的输入,这些函数是 mutate() 的参数。如 cmets 中所述,可以使用 group_by() 将右侧函数的输入分解为子组。这消除了mutate() 中对原始问题中指定的条件逻辑的需求。
我们将通过计算原始帖子中的cond_disp 来说明,并包含n 以计算摘要数据中包含的行数。
mtcars %>% group_by(vs) %>%
mutate(cond_disp = sum(disp),
n = n()) -> result
result[,c("vs","n","cond_disp","disp")]
# A tibble: 32 x 4
# Groups: vs [2]
vs n cond_disp disp
<dbl> <int> <dbl> <dbl>
1 0 18 5529. 160
2 0 18 5529. 160
3 1 14 1854. 108
4 1 14 1854. 258
5 0 18 5529. 360
6 1 14 1854. 225
7 0 18 5529. 360
8 1 14 1854. 147.
9 1 14 1854. 141.
10 1 14 1854. 168.
# … with 22 more rows
mutate() 方法在需要逐行计算百分比值时非常有用,其中百分比的分母是按组组合内的列的总和。为了说明这一点,我们将计算 V 型发动机与直列发动机的总排量百分比,打印结果,并打印pct_disp 的总和,以说明 V 型发动机等于 100。
mtcars %>% group_by(vs) %>%
mutate(pct_disp = 100* disp / sum(disp),
n = n()) -> result
result[result$vs==0,c("vs","n","disp","pct_disp")]
sum(result$pct_disp[result$vs==0])
# A tibble: 18 x 4
# Groups: vs [1]
vs n disp pct_disp
<dbl> <int> <dbl> <dbl>
1 0 18 160 2.89
2 0 18 160 2.89
3 0 18 360 6.51
4 0 18 360 6.51
5 0 18 276. 4.99
6 0 18 276. 4.99
7 0 18 276. 4.99
8 0 18 472 8.54
9 0 18 460 8.32
10 0 18 440 7.96
11 0 18 318 5.75
12 0 18 304 5.50
13 0 18 350 6.33
14 0 18 400 7.23
15 0 18 120. 2.18
16 0 18 351 6.35
17 0 18 145 2.62
18 0 18 301 5.44
> sum(result$pct_disp[result$vs==0])
[1] 100
何时使用 summarise()
dplyr::summarise() 如果想要汇总数据而不向管道中的输入数据框添加额外的列,则很有用。 summarise() 的结果是管道中 group_by() 规范中的每个变量组合的一行,汇总数据的列。
mtcars %>% group_by(vs) %>%
summarise(cond_disp = sum(disp),
n = n())
# A tibble: 2 x 3
vs cond_disp n
<dbl> <dbl> <int>
1 0 5529. 18
2 1 1854. 14
逐行计算
如果需要使用 R 函数计算行内各列的值,可以使用 rowwise() 函数来防止 mutate() 在 mutate() 内方程右侧的函数中使用多行.
为了说明,我们将对vs、am 的值求和。请注意,输出中n = n() 的结果对于打印的每一行都是 1。
mtcars %>% rowwise(.) %>%
mutate(cond_binary = sum(vs,am),
n = n()) -> result
result[,c("vs","am","n","cond_binary")]
# A tibble: 32 x 4
# Rowwise:
vs am n cond_binary
<dbl> <dbl> <int> <dbl>
1 0 1 1 1
2 0 1 1 1
3 1 1 1 2
4 1 0 1 1
5 0 0 1 0
6 1 0 1 1
7 0 0 1 0
8 1 0 1 1
9 1 0 1 1
10 1 0 1 1
# … with 22 more rows