Если я напишу это в фрагменте файла .Rmd в RStudio
library(dplyr)
df %>%
group_by(var)
а затем я запускаю кусок, вывод будет иметь
A tibble: 789542 x 8 Groups: var[8]
сверху на печатном фрейме данных.
Я нахожу эту информацию очень полезной, и я хотел бы иметь ее также в html-документе, в который я вяжу этот файл .Rmd, но пока мне это не удалось.
Я перепробовал все варианты
output:
html_document:
df_print:
их пейджинг, tibble, kable и kable-scroll.
Я не знаю, есть ли еще какие-то или вы можете настроить их с помощью необязательных аргументов, обширные поиски в Google ни к чему не привели. Я бы не знал, как начать писать пользовательскую функцию.
Я также пробовал DT:::datatable()
, но он показывает только количество строк, а не групп.
Я знаю, что могу передать дополнительные nrow()
и n_groups()
каждому df, но я хотел бы избежать этого, если это возможно.
Этот html-документ будет представлен на очень простой странице github. Я знаю, что blogdown/hugo и новый Quarto более мощные, и, возможно, они предлагают решение, но я не знаю, хочу ли я научиться их использовать (я слышал, что они намного сложнее) для этого небольшого проекта.
Чтобы отобразить информацию tibble
(количество строк x столбцов и информацию о группе) вместе с постраничным выводом, мы можем написать пользовательскую функцию, изменив функцию print.paged_df (которая используется внутри rmarkdown для функции df_print
) и использовать CSS для красивого форматирования вывода.
---
title: "Showing data group info"
output: html_document
---
# R markdown
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, df_print = "info_paged")
```
```{r, echo=FALSE}
info_paged_print <- function(x, options) {
tibble_info <- paste0("<div class=\"tibble-info\">A tibble: ", nrow(x), " x ", ncol(x), "</div>")
group_info <- paste0("<div class=\"group-info\">Groups: ",
paste0(group_vars(x), collapse = ", "),
" [", nrow(group_keys(x)), "]", "</div>")
if (dplyr::is_grouped_df(x)) {
tab_info <- paste0("<div class=\"info\">", tibble_info, " ", group_info, "</div>")
cat(tab_info)
} else {
cat(paste0("<div class=\"info\">", tibble_info, "</div>"))
}
knitr::asis_output(
rmarkdown:::paged_table_html(x, options = attr(x, "options")),
meta = list(
dependencies = rmarkdown:::html_dependency_pagedtable()
)
)
}
knitr::opts_hooks$set(df_print = function(options) {
if (options$df_print == "info_paged") {
options$render = info_paged_print
options$comment = ""
options$results = "asis"
}
options
})
```
```{css, echo=FALSE}
.tibble-info,
.group-info {
display: inline-block;
padding: 15px;
}
.info {
margin-top: 5px;
margin-bottom: 5px;
border: 1px solid #ccc;
border-radius: 4px;
font-weight: 600;
color: #999898;
}
```
```{r, message=FALSE, warning=FALSE, comment = ""}
library(dplyr)
```
## Grouped Data
```{r}
mtcars %>%
group_by(am, vs)
```
## Ungrouped Data
```{r}
head(mtcars)
```
## logical filtering
```{r}
mtcars %>%
mutate(
logical = if_else(mpg > mean(mpg), TRUE, FALSE)
) %>%
filter(logical)
```
И вы можете настроить CSS для отображения информации tibble
по своему усмотрению.
Да, вы должны были упомянуть об этом в своем вопросе. Теперь это делает мой ответ совершенно бесполезным.
@goingdeep, я полностью обновил свой ответ.
спасибо @shafee, это было очень мило с твоей стороны. Я получаю сообщение об ошибке, если передаю filter() логическому столбцу, например filter(LogicalColumn). В нем говорится: «Ошибка в UseMethod («group_vars»): нет применимого метода для« group_vars », примененного к объекту класса «логический». Вызовы: <Anonymous> ... withVisible -> value_fun -> fun -> paste0 -> paste0 - > групповые_переменные.
не беспокойтесь об исправлении, вы уже сделали все возможное, и я не могу просить вас исправить каждую маленькую ошибку, с которой я могу столкнуться, так как в этом проекте есть несколько продвинутых каналов dplyr, так что это может стать для вас бесконечной задачей. .
@goingdeep, можете ли вы вставить код, из которого возникает вышеуказанная ошибка?
df %>% mutate(LogicalColumn = if_else(Var == "Value", TRUE, FALSE)) %>% filter(LogicalColumn)
Я не получаю никаких ошибок, и я обновил свой ответ, чтобы показать, что ваш случай работает для меня. И если этот ответ поможет вам, вы должны проголосовать за него и принять его :)
спасибо за намек, и да, ошибка была вызвана строками вроде «2 == 2». Я решил это, добавив 'df_print = "paged" в параметры фрагмента. Ответ одобрен и принят :)
Теперь есть две другие «проблемы», одна из которых заключается в том, что я хотел бы также показать, когда фрейм данных является строковым, например, когда я использую «rowwise()» или «nest_by()». Я попытаюсь изменить ваш код и в случае неудачи открою другой вопрос. 'group_split()' и 'group_walk()' — две другие хитрые функции, над которыми мне нужно поразмышлять подробнее.
Я попытался воспроизвести это с помощью простой пользовательской функции. Результат не совсем тот же, но он может соответствовать вашим потребностям.
Ниже приведена демонстрация с использованием набора данных mtcars и столбца «cyl».
PrintSummary <- function(df, col){
Line1 <- paste0("A tibble: ", nrow(df), " x ", ncol(df))
Line2 <- paste0("Groups: ", col, "[", length(unique(df[, col])), "]")
message(Line1)
message(Line2)
}
PrintSummary(mtcars, "cyl")
Вывод должен быть следующим:
A tibble: 32 x 11
Groups: cyl[3]
спасибо и вам, как вы думаете, можно ли установить значение по умолчанию для столбца, когда фрейм данных не сгруппирован?
Пожалуйста! Боюсь, я не знаю таких вариантов по умолчанию. Однако вы можете добавить атрибут (с указанием столбца для группировки) в data.frame, а затем изменить функцию для поиска атрибута data.frame, если столбец не указан.
еще раз спасибо за ответ, я буду использовать решение shafee, но я ценю ваше так же, как и я, безусловно, могу чему-то научиться из него.
спасибо за ответ, я ценю это, и извиняюсь, что я забыл упомянуть, что я знаю об этом решении, которое я исключил, потому что оно выглядит довольно уродливо, плюс оно не позволяет перемещаться по строкам фрейма данных, как выгружаемый вариант делает.