我正在尝试在计算计数和比例后添加总行。我已经为其创建了一个函数,但在传递!!sym(group_var)
时返回错误
freq_table <- function(df, group_var) {
group_var2 <- !!sym(group_var)
df %>%
group_by_at(group_var) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n)) %>%
ungroup %>%
bind_rows(., data.frame(
group_var2 := "Grand Total",
sapply(. %>% dplyr::select_if(is.numeric),
function(x) sum(x, na.rm = T)) %>% t()
))
}
freq_table(iris, group_var = "Species")
使用adorn_totals
我们可以更容易地做到这一点
freq_table <- function(df, group_var) {
df %>%
dplyr::group_by(across(all_of(group_var))) %>%
dplyr::summarise(n = n(), .groups = 'drop') %>%
dplyr::mutate(freq = n / sum(n)) %>%
janitor::adorn_totals(name = "Grand Total")
}
-测试
freq_table(iris, group_var = "Species")
# Species n freq
# setosa 50 0.3333333
# versicolor 50 0.3333333
# virginica 50 0.3333333
# Grand Total 150 1.0000000
应在tidyverse函数中使用!!
。此外,这里我们不需要sym
或!!
,因为OP使用的是group_by_at
,它可以取一个字符串,然后赋值(:=
(,lhs可以是字符串。通过sapply
和t
传输的循环修改了bind_rows
,因为这返回了matrix
。我们可以使用summarise
和across
在numeric
列上循环,并使用add_row
在底部添加新行
freq_table <- function(df, group_var) {
df %>%
group_by_at(all_of(group_var)) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n)) %>%
ungroup %>%
add_row(
!!group_var := "Grand Total",
{.} %>%
summarise(across(where(is.numeric), sum, na.rm = TRUE)))
}
-测试
freq_table(iris, group_var = "Species")
# A tibble: 4 x 3
# Species n freq
# <chr> <int> <dbl>
#1 setosa 50 0.333
#2 versicolor 50 0.333
#3 virginica 50 0.333
#4 Grand Total 150 1