RObservations #42: Using the jinjar and tidyRSS packages to make a simple newsletter template
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Introduction
Jinja is a powerful templating engine that is useful in a variety of contexts. Recently, I discovered how its possible to use the power of Jinja syntax in R with the jinjar
package written by David C Hall. With jinjar
and the tidyRSS
package by Robert Myles it is possible to make an email template that can provide short and informative updates. In his blog, I’m going to share how the jinjar
and tidyRSS
packages work and show how to combine them to make a simple daily email newsletter.
How jinjar
Works
jinjar
allows for users to create templates with regular text (or HTML or Markdown) and Jinja code. While the jinjar
package has some limitations (as mentioned by the author), it is still very powerful.As an example, I’ll use the bee colonies data made available by Thomas Mock’s TidyTuesday repository to make a template that returns the average annual bee colony loss and total number of bees lost.
First, lets transform the data appropriately:
library(tidyverse) # Load the data bee_colonies <- readr::read_csv( 'https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2022/2022-01-11/colony.csv', show_col_types = FALSE ) # Some aggregation annual_bee_loss <- bee_colonies %>% group_by(year) %>% summarize( average_colony_loss_pct = round(mean(colony_lost_pct, na.rm = T), 2), total_colony_loss = sum(colony_lost, na.rm = T) %>% scales::comma() ) annual_bee_loss ## # A tibble: 7 × 3 ## year average_colony_loss_pct total_colony_loss ## <dbl> <dbl> <chr> ## 1 2015 12.2 3,444,720 ## 2 2016 11.4 3,316,520 ## 3 2017 11.5 2,814,400 ## 4 2018 12.1 3,034,140 ## 5 2019 11.9 2,483,820 ## 6 2020 9.96 3,097,220 ## 7 2021 10.4 1,256,980
Once the data is appropriately formatted, we can use jinjar
to put the relevant data in a Markdown template:
library(jinjar) # Jinja template template<- ' ## Annual Bee Colony Loss In The United States {% for loss in losses -%} * {{loss.year}}: {{loss.average_colony_loss_pct}}% ({{loss.total_colony_loss}} bees) {% endfor -%} ' # Render the template with the annual bee loss data template %>% jinjar::render(losses = annual_bee_loss) %>% writeLines() ## ## ## Annual Bee Colony Loss In The United States ## ## * 2015: 12.15% (3,444,720 bees) ## ## * 2016: 11.36% (3,316,520 bees) ## ## * 2017: 11.47% (2,814,400 bees) ## ## * 2018: 12.1% (3,034,140 bees) ## ## * 2019: 11.86% (2,483,820 bees) ## ## * 2020: 9.96% (3,097,220 bees) ## ## * 2021: 10.35% (1,256,980 bees)
We can even convert the Markdown text to a html file by rendering the text:
library(htmltools) library(markdown) template %>% jinjar::render(losses = annual_bee_loss) %>% renderMarkdown(text = .) %>% markdownToHTML(text = .) %>% htmlTemplate(text_ = .) %>% html_print()
This gives the following output:
How tidyRSS
Works
The tidyRSS
package enables users to convert an RSS feed to a data frame with one function.
Suppose I’m interested in the latest R-Bloggers posts from today and yesterday. All that needs to be done is to supply the feed link to the tidyfeed()
function, filter the publication date with dplyr
‘s filter()
function and use lubridate
to parse dates accordingly.
(using glimpse()
to show all the columns of data)
library(tidyRSS) library(lubridate) tidyfeed("R-bloggers.com/feed") %>% filter(as.Date(item_pub_date) == today() | as.Date(item_pub_date) == today() - 1) %>% glimpse() ## Rows: 13 ## Columns: 14 ## $ feed_title <chr> "R-bloggers", "R-bloggers", "R-bloggers", "R-bloggers", "R-bloggers", "R-bloggers", "R-bloggers"… ## $ feed_link <chr> "https://www.r-bloggers.com", "https://www.r-bloggers.com", "https://www.r-bloggers.com", "https… ## $ feed_description <chr> "R news and tutorials contributed by hundreds of R bloggers", "R news and tutorials contributed … ## $ feed_language <chr> "en-US", "en-US", "en-US", "en-US", "en-US", "en-US", "en-US", "en-US", "en-US", "en-US", "en-US… ## $ feed_pub_date <dttm> 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 … ## $ feed_last_build_date <dttm> 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 … ## $ feed_category <chr> "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers"… ## $ feed_generator <chr> "https://wordpress.org/?v=5.5.11", "https://wordpress.org/?v=5.5.11", "https://wordpress.org/?v=… ## $ item_title <chr> "PCA for Categorical Variables in R", "Whisperings in the Academy", "Some problems related to Di… ## $ item_link <chr> "https://www.r-bloggers.com/2022/11/pca-for-categorical-variables-in-r/", "https://www.r-blogger… ## $ item_description <chr> "The post PCA for Categorical Variables in R appeared first on finnstats.If you are interested t… ## $ item_pub_date <dttm> 2022-11-20 13:32:06, 2022-11-20 13:12:43, 2022-11-19 15:08:18, 2022-11-19 15:07:53, 2022-11-19 … ## $ item_guid <chr> "https://finnstats.com/?p=16971", "https://www.weirddatascience.net/?p=4385", "https://r-posts.c… ## $ item_category <chr> "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers"…
Now that we know how to use the jinjar
and tidyRSS
packages, lets put them together to make a automated newsletter called “Ben’s R Update”!
Using jinjar
and tidyRSS
to make an R related newsletter
In my hypothetical newsletter “Ben’s R Update”, I share recent R Blogs, r/Rlanguage posts and some available R job postings that are available. This can all be gathered from the R-Bloggers, r/RLanguage and Indeed RSS feeds with tidyRSS
and templated with jinjar
.
The code to do this is:
library(tidyRSS) library(dplyr) library(lubridate) library(jinjar) library(htmltools) library(markdown) template<- '# Ben\'s R Update {{date}} ## Some R Blogs you might have missed {% for blog in blogs -%} * {{blog.item_title}} : {{blog.item_link}} ({{blog.feed_pub_date}}) {% endfor -%} ## New Reddit posts on r/RProgramming {% for posts in redditPosts -%} * {{posts.entry_title}} : {{posts.entry_link}} ({{posts.entry_published}}) {% endfor -%} ## New Job Postings For R Programmers {% for job in jobPostings -%} * {{job.item_title}} : {{job.item_link}} ({{job.item_pub_date}}) {% endfor -%} ' # Make Email Template and Write to Markdown File template %>% jinjar::render( blogs = tidyRSS::tidyfeed("R-bloggers.com/feed") %>% filter( as.Date(item_pub_date) == today() | as.Date(item_pub_date) == today() - 1 ), redditPosts = tidyRSS::tidyfeed("https://www.reddit.com/r/Rlanguage.rss") %>% filter( as.Date(entry_published) == today() | as.Date(entry_published) == today() - 1 ), jobPostings = tidyRSS::tidyfeed("https://rss.indeed.com/rss?q=R+Programming") %>% filter( as.Date(item_pub_date) >= today() | as.Date(item_pub_date) <= today() - 1 ), date = today() ) %>% renderMarkdown(text = .) %>% markdownToHTML(text = .) %>% htmlTemplate(text_ = .) %>% html_print()
The output is:
And there you have it! A simple automated newsletter ready to send out!
Conclusion
The jinjar
package is a powerful library for dynamic rendering and the example that I provided is really basic. Some more sophisticated examples of using jinjar
would be rendering HTML in Shiny Apps and Blogdown sites. I haven’t tried these out yet but I’m sure the use cases would be extensive!
This blog also only focused on making the email template. For sending out the newsletter to a list of contacts, check out the emayili
package and set up a cron job to automate it. Let me know if you try it!
Thank you for reading!
Want to see more of my content?
Be sure to subscribe and never miss an update!
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.