I have a dataframe with data from a survey. I would like to produce a report in table format with the frequencies of each variable.
So working with the dataset mtcars, having this:
> count(mtcars, cyl)
cyl n
1 4 11
2 6 7
3 8 14
> count(mtcars, gear)
gear n
1 3 15
2 4 12
3 5 5
I would like to produce a table like this (or something similar):
variable | n |
---|---|
cyl | |
4 | 11 |
6 | 7 |
8 | 14 |
gear | |
3 | 15 |
4 | 12 |
5 | 5 |
Any idea as to how this may be achievable?
CodePudding user response:
We can write a nested pair of functions to map count
to multiple variables and row-bind the results, using a little tidy evaluation:
library(tidyverse)
count_multi <- function(.data, ...) {
count_var <- function(var, .data) {
.data %>%
count(Value = as.character({{ var }})) %>% # coerce to character to
mutate( # allow multiple var types
Variable = as.character(ensym(var)),
.before = everything()
)
}
map_dfr(enquos(...), count_var, .data = .data)
}
mtcars %>%
count_multi(cyl, gear)
Output:
Variable Value n
1 cyl 4 11
2 cyl 6 7
3 cyl 8 14
4 gear 3 15
5 gear 4 12
6 gear 5 5
I believe you can use kableExtra::pack_rows()
to create subheaders for each Variable
in markdown.
CodePudding user response:
The below gets us the output in slightly different format. However, it does allow for subset (using column variable
which OP's requirement does not.)
library(data.table)
df <- setDT(copy(mtcars))
# select columns as grouping by continuous variables is not appropriate
x <- c('cyl', 'gear')
y <- lapply(x, \(i) df[, .N, i])
names(y) <- x
y <- rbindlist(y, idcol=T, use.names=F)
names(y) <- c('variable', 'class', 'count')
variable class count
1: cyl 6 7
2: cyl 4 11
3: cyl 8 14
4: gear 4 12
5: gear 3 15
6: gear 5 5