我想在同一时间对多个字符变量使用summarise_at
和mutate_at
。我已经看过许多使用整数变量的例子,但我不能弄清楚字符变量。下面是我用来为字符(或因子)变量生成描述性统计信息的代码。
library(tidyverse)
# First block of code
starwars %>%
group_by(gender) %>%
summarise (n = n()) %>%
mutate(totalN = (cumsum(n))) %>%
mutate(percent = round((n / sum(n)), 3)) %>%
mutate(cumpercent = round(cumsum(freq = n / sum(n)),3))
这会产生:
A tibble: 5 x 5
gender n totalN percent cumpercent
<chr> <int> <int> <dbl> <dbl>
1 female 19 19 0.218 0.218
2 hermaphrodite 1 20 0.011 0.230
3 male 62 82 0.713 0.943
4 none 2 84 0.023 0.966
5 <NA> 3 87 0.034 1.000
我想生成同样的东西,但是对于多个字符(或因子)变量一次。在这种情况下,让我们使用变量gender
和eye_color
这就是我的尝试:
starwars %>%
summarise_at(vars(gender, eyecolor) (n = n()) %>%
mutate_at(vars(gender, eyecolor) (totalN = (cumsum(n))) %>%
mutate_at(vars(gender", "eyecolor) (percent = round((n / sum(n)), 3)) %>%
mutate_at(vars(gender, eyecolor) (cumpercent = round(cumsum(freq = n / sum(n)),3))))))
我收到以下错误:
Error in eval(expr, envir, enclos) : attempt to apply non-function
我了解有使用funs
调用的内置函数,但我不想使用它们。我尝试过以不同的方式使用代码来使其工作,但是已经很短了。
我想要制作的是这样的:
A tibble: 5 x 5
gender n totalN percent cumpercent
<chr> <int> <int> <dbl> <dbl>
1 female 19 19 0.218 0.218
2 hermaphrodite 1 20 0.011 0.230
3 male 62 82 0.713 0.943
4 none 2 84 0.023 0.966
5 <NA> 3 87 0.034 1.000
A tibble: 15 x 5
eye_color n totalN percent cumpercent
<chr> <int> <int> <dbl> <dbl>
1 black 10 10 0.115 0.115
2 blue 19 29 0.218 0.333
3 blue-gray 1 30 0.011 0.345
4 brown 21 51 0.241 0.586
5 dark 1 52 0.011 0.598
6 gold 1 53 0.011 0.609
7 green, yellow 1 54 0.011 0.621
8 hazel 3 57 0.034 0.655
9 orange 8 65 0.092 0.747
10 pink 1 66 0.011 0.759
11 red 5 71 0.057 0.816
12 red, blue 1 72 0.011 0.828
13 unknown 3 75 0.034 0.862
14 white 1 76 0.011 0.874
15 yellow 11 87 0.126 1.000
也许循环会更好?现在我有很多行代码来为每个字符变量生成描述性统计信息,因为我必须为每个变量运行第一个代码块(如上所述)。如果我能列出我想要使用的变量并在第一个代码块中运行它们,那就太棒了。
答案 0 :(得分:3)
根据您的预期输出,mutate_at
不是您想要的,因为它会在所选列上发生变化。您要做的是分别group_by
gender
和eye_color
。这是将摘要代码编写到函数中的好地方:
library(tidyverse)
library(rlang)
summary_func = function(group_by_var){
group_by_quo = enquo(group_by_var)
starwars %>%
group_by(!!group_by_quo) %>%
summarise(n = n()) %>%
mutate(totalN = (cumsum(n)),
percent = round((n / sum(n)), 3),
cumpercent = round(cumsum(freq = n / sum(n)),3))
}
<强>结果:强>
> summary_func(gender)
# A tibble: 5 x 5
gender n totalN percent cumpercent
<chr> <int> <int> <dbl> <dbl>
1 female 19 19 0.218 0.218
2 hermaphrodite 1 20 0.011 0.230
3 male 62 82 0.713 0.943
4 none 2 84 0.023 0.966
5 <NA> 3 87 0.034 1.000
> summary_func(eye_color)
# A tibble: 15 x 5
eye_color n totalN percent cumpercent
<chr> <int> <int> <dbl> <dbl>
1 black 10 10 0.115 0.115
2 blue 19 29 0.218 0.333
3 blue-gray 1 30 0.011 0.345
4 brown 21 51 0.241 0.586
5 dark 1 52 0.011 0.598
6 gold 1 53 0.011 0.609
7 green, yellow 1 54 0.011 0.621
8 hazel 3 57 0.034 0.655
9 orange 8 65 0.092 0.747
10 pink 1 66 0.011 0.759
11 red 5 71 0.057 0.816
12 red, blue 1 72 0.011 0.828
13 unknown 3 75 0.034 0.862
14 white 1 76 0.011 0.874
15 yellow 11 87 0.126 1.000
我们的想法是将您的摘要代码转换为函数,以便您可以在不同的group_by
变量上应用相同的代码。来自enquo
的{{1}}将提供的代码提取到rlang
,并将其与调用group_by_var
的环境捆绑在一起。然后,您可以使用quosure
取消引用!!
步骤中的group_by_quo
。这样可以进行非标准评估(即键入group_by
而不是summary_func(gender)
。
如果您不想为summary_func("gender")
的每个变量拨打summary_func
,可以将group_by
代码包含在dplyr
map
中并且取消引用作为purrr
参数提供的group_by_quo
的每个参数。请注意从...
到enquo
的更改,以将quos
的每个参数转换为...
的列表:
quosure
您现在可以执行此操作:
summary_func = function(...){
group_by_quo = quos(...)
map(group_by_quo, ~{
starwars %>%
group_by(!!.x) %>%
summarise(n = n()) %>%
mutate(totalN = (cumsum(n)),
percent = round((n / sum(n)), 3),
cumpercent = round(cumsum(freq = n / sum(n)),3))
})
}
或带有summary_func(gender, eye_color)
的字符变量名称向量:
group_by
<强>结果:强>
group_vars = c("gender", "eye_color")
summary_func(!!!syms(group_vars))