Как говорит Джон, пакеты kable (и kableExtra ) могут помочь отформатировать таблицу, когда у вас есть группы, плюс множество других приятных функций. Однако получение выходных данных в запрошенном формате требует некоторого изменения формы.
Я буду использовать набор данных survey из пакета MASS .
data(survey, package="MASS")
str(survey) # showing only a subset of vars.
'data.frame': 237 obs. of 12 variables:
$ Sex : Factor w/ 2 levels "Female","Male": 1 2 2 2 2 1 2 1 2 2 ...
$ Fold : Factor w/ 3 levels "L on R","Neither",..: 3 3 1 3 2 1 1 3 3 3 ...
$ Age : num 18.2 17.6 16.9 20.3 23.7 ...
Цель состоит в том, чтобы получить таблицу, подобную этой:
library(tidyverse)
library(knitr)
library(kableExtra)
Измените данные, используя gather
/ spread
и сохраните его для последующего рендеринга с помощью kable.
tbl <- survey %>%
select(Sex, Age, Fold) %>%
filter_all(all_vars(!is.na(.))) %>%
group_by(Fold, Sex) %>%
summarise(n = n(),
age.mean = sprintf("%.1f", mean(Age, na.rm=TRUE)),
age.sd = sprintf("%.1f", sd(Age, na.rm=TRUE))) %>%
gather(key, value, n:age.sd) %>% #
unite(Group, Sex, key) %>% # Could have used pivot_wider...see below.
spread(Group, value) #
Возвращает:
# A tibble: 3 x 7
# Groups: Fold [3]
Fold Female_age.mean Female_age.sd Female_n Male_age.mean Male_age.sd Male_n
<fct> <chr> <chr> <chr> <chr> <chr> <chr>
1 L on R 21.4 9.1 48 19.6 4.0 50
2 Neither 19.4 1.3 6 21.2 5.2 12
3 R on L 19.7 5.0 64 20.8 7.6 56
Обратите внимание, как переменные для Female отображаются перед переменными для Male. Если бы я использовал:
pivot_wider(names_from=Sex, values_from=c(n, age.mean, age.sd))
, я бы получил:
# A tibble: 3 x 7
# Groups: Fold [3]
Fold n_Female n_Male age.mean_Female age.mean_Male age.sd_Female age.sd_Male
<fct> <int> <int> <chr> <chr> <chr> <chr>
1 L on R 48 50 21.4 19.6 9.1 4.0
2 Neither 6 12 19.4 21.2 1.3 5.2
3 R on L 64 56 19.7 20.8 5.0 7.6
, которые не соответствуют нашей цели. Я мог бы изменить, но зачем беспокоиться, если спред может сделать это для вас? Далее переименуйте столбцы. Функция rename
из dplyr не допускает дублирование имен, поэтому давайте используем базовую R.
tbl <- setNames(tbl, nm=sub(".+_", "", names(tbl)))
Затем используйте kable
для применения форматирования.
kable(tbl, align=c('l', rep('c', 6))) %>%
kable_styling("striped") %>%
add_header_above(c(" " = 1, "Female" = 3, "Male" = 3))