I have this dataframe
products <- c("Product1", "Product2", "Product3")
departments <- c("Dept1", "Dept2", "Dept3")
campaigns <- c("Campaign1", "Campaign2", "Campaign3", "Campaign4", "Campaign5")
agents <- c("Agent1", "Agent2", "Agent3", "Agent4", "Agent5")
combinations <- expand.grid(Product = products,
Department = departments,
Campaign = campaigns,
Agent = agents)
grouped_data <- combinations %>%
group_by(Product, Department, Campaign, Agent) %>%
summarize(Total_Sales = sum(Sales),
Average_Sales = mean(Sales))
I'd like to print in Rmarkdown programmatically without manually creating so many sections in my document so I created this function:
render_content <- function(dataframe) {
split_data <- split(dataframe, f = list(dataframe$Product, dataframe$Campaign))
for (product in unique(dataframe$Product)) {
cat(paste0("<h2>", product, "</h2>\n"))
product_data <- split_data[grepl(product, names(split_data))]
for (campaign in unique(dataframe$Campaign)) {
campaign_key <- paste(product, campaign, sep = ".")
if (campaign_key %in% names(product_data)) {
cat(paste0("<h3>", campaign, "</h3>\n"))
table_html <- reactable(product_data[[campaign_key]],
defaultPageSize = 5,
minRows = 0)
cat(as.character(htmltools::as.tags(table_html)))
}
}
}
}
I put this chunk to my rmarkdown document but only h2 and h3 tags are rendered, I believe it has something to do with the necessity to include tags in documents so I tried several variants of it, but nothing helps.
{r, include=FALSE}
htmltools::tagList(reactable())
{r results='asis', echo=FALSE}
render_content(grouped_data)
Here is a reproducible example of one approach how you can achieve your aims. It uses a child document.
The next part is your main .Rmd file.
---
title: "A title"
output: html_document
---
```{r setup, include=TRUE}
knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
## {reactable} used with namespace
```
# Data
```{r}
dat <- expand.grid(
products = c(paste("prd", 1:3, sep = "_")),
departments = c(paste("dept", 1:3, sep = "_")),
campaigns = c(paste("camp", 1:3, sep = "_") ),
agents = c(paste("agent", 1:3, sep = "_"))
) %>%
mutate(sales = rnorm(81, 5000, 500)) %>%
filter(!(products == "prd_1" & campaigns == "camp_3"))
```
Exclude the combination of product 1 and campaign 3 since it might be another
interesting way to see that the headers/sections will be generated correctly.
# Function(s)
```{r}
func_render_content <- function(x_dat) {
param_env <- new.env()
param_env$x_dat <- x_dat
for(product_i in unique(x_dat$products)) {
cat(paste0("<h2>", product_i, "</h2>\n"))
product_data <- x_dat %>% filter(products == product_i)
for(campaign_i in unique(x_dat$campaigns)) {
if(campaign_i %in% unique(product_data$campaigns)) {
cat(paste0("<h3>", campaign_i, "</h3>\n"))
param_env$product_i <- product_i
param_env$campaign_i <- campaign_i
cat(knitr::knit_child(
'so-content.Rmd',
envir = param_env,
quiet = TRUE
))
cat("\n\nThat's it on", product_i, "and", campaign_i, "end of sentence.")
}
}
}
}
```
```{r}
func_render_content_your_attempt <- function(x_dat) {
for (product_i in unique(x_dat$products)) {
cat(paste0("<h2>", product_i, "</h2>\n"))
product_data <- x_dat %>% filter(products == product_i)
for (campaign_i in unique(x_dat$campaigns)) {
if (campaign_i %in% unique(product_data$campaigns)) {
cat(paste0("<h3>", campaign_i, "</h3>\n"))
x_dat %>%
filter(products == product_i & campaigns == campaign_i) %>%
reactable::reactable(defaultPageSize = 5)
}
}
}
}
```
# This works
```{r, results='asis'}
func_render_content(dat)
```
# Your attempt, does not what you want
In the sense of completeness.
```{r, results='asis'}
func_render_content_your_attempt(dat)
```
The next part is a separate .Rmd file called so-content.Rmd
.
---
title: "section-content"
---
```{r, echo=FALSE}
x_dat %>%
filter(products == product_i & campaigns == campaign_i) %>%
reactable::reactable(defaultPageSize = 5)
```