
<rss version="2.0">
    <channel>
        <title>jmablog</title>
        <link>https://jmablog.com/</link>
        <image>
            <url>https://jmablog.com/card.png</url>
            <title>jmablog.com</title>
            <link>https://jmablog.com</link>
        </image>
        <description>Recent content on jmablog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-gb</language>
        <copyright>© 2020 James Adams</copyright>
        
        <item>
            <title>What was the best year for a saxophone lover to be listening to the Billboard Top 100?</title>
            <link>https://jmablog.com/post/numberones/</link>
            <pubDate>Thu, 26 Feb 2026 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/numberones/</guid>
            <description>&lt;p&gt;&lt;em&gt;(&lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;Tidy Tuesday&lt;/a&gt; is a project to supply weekly data sets for R users to practice their coding skills on. You can find &lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;full details here&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I turned to my wife in the car the other day and said, out of nowhere: &amp;ldquo;You know, I love a bit of sax in a song.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;She laughed.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;But I was deadly serious.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Coincedentally, while looking through the Tidy Tuesday archives for some data to play around with in R after not using the language for a while, I found the &lt;a href=&#34;https://github.com/rfordatascience/tidytuesday/blob/main/data/2025/2025-08-26/readme.md&#34;&gt;Billboard Hot 100 Number Ones&lt;/a&gt; data set. And it contains a flag for &amp;ldquo;&amp;hellip;if the song contains a saxophone&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Hell yeah.&lt;/p&gt;
&lt;p&gt;Which in turn got me wondering, which year had the most sax in it?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;sax_tiny.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Sadly, since my birth in 1987, only 11 years in total have even had a sax-song go to number 1. And since I was old enough to meaningfully care, i.e. 1994, only &lt;em&gt;5&lt;/em&gt; years had a sax-tastic hit. What are we even doing as a society? I say the AI can take us, for truly we lost our souls decades ago.&lt;/p&gt;
&lt;p&gt;Two songs in particular though hold down the fort - Whitney Houston&amp;rsquo;s &amp;ldquo;I Will Always Love You&amp;rdquo; in 1992, with a whopping 14 weeks at no. 1, pushing 1992 to the highest scoring year (31%) with the assistance of The Heights&amp;rsquo; &amp;ldquo;How Do You Talk To An Angel&amp;rdquo;. &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Then, in 2015, Bruno Mars&amp;rsquo; &amp;ldquo;Uptown Funk&amp;rdquo; was a shining reprieve in the darkness and also achieved 14 weeks at no. 1, but sadly struggled on alone, leaving 2015 at only 27% saxy.&lt;/p&gt;
&lt;p&gt;Code (also on &lt;a href=&#34;https://github.com/jmablog/jmablog-code-snippets&#34;&gt;GitHub&lt;/a&gt;):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;library(tidyverse)
library(ggtext)
library(tidytuesdayR)
library(tinieR)

# importing data

data &amp;lt;- tidytuesdayR::tt_load(&amp;#39;2025-08-26&amp;#39;)
songs &amp;lt;- data$billboard

# data manip

sax_songs &amp;lt;- songs |&amp;gt;
    filter(saxophone == 1) |&amp;gt; 
    separate(cdr_genre, into = c(&amp;#34;main_genre&amp;#34;, &amp;#34;other_genres&amp;#34;), sep = &amp;#34;;&amp;#34;, fill = &amp;#34;right&amp;#34;) |&amp;gt; 
    replace_na(list(main_genre = &amp;#34;Rock&amp;#34;)) |&amp;gt; 
    separate(date, c(&amp;#34;year&amp;#34;, &amp;#34;month&amp;#34;, &amp;#34;day&amp;#34;), sep = &amp;#34;-&amp;#34;, remove = FALSE) |&amp;gt;
    select(year, weeks_at_number_one, main_genre) |&amp;gt; 
    group_by(year) |&amp;gt; 
    summarise(perc_of_year = (sum(weeks_at_number_one)/52)) |&amp;gt; 
    ungroup() |&amp;gt; 
    mutate(year = as.Date(paste(year, &amp;#34;01&amp;#34;, &amp;#34;01&amp;#34;, sep = &amp;#34;-&amp;#34;)))

# plot

sax_songs |&amp;gt; 
    ggplot(aes(year, perc_of_year)) +
    geom_point(colour = &amp;#34;#E03135&amp;#34;, size = 2) +
    scale_y_continuous(labels=scales::percent) +
    scale_x_date(date_breaks = &amp;#34;10 year&amp;#34;, date_labels = &amp;#34;%Y&amp;#34;, expand = expansion(add = 0)) +
    xlim(c(as.Date(&amp;#34;1959-01-01&amp;#34;), as.Date(&amp;#34;2023-01-01&amp;#34;))) +
    theme(legend.position = &amp;#34;none&amp;#34;,
        axis.text.x = element_text(face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#4D556B&amp;#34;),
        axis.text.y = element_text(face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#4D556B&amp;#34;),
        axis.title.y = element_text(face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#4D556B&amp;#34;),
        #axis.ticks.y = element_blank(),
        axis.line = element_line(colour = &amp;#34;#4D556B&amp;#34;),
        #panel.border = element_rect(color = &amp;#34;black&amp;#34;, fill = NA),
        panel.grid = element_blank(),
        panel.grid.major.y = element_line(size = 0.3, colour = &amp;#34;black&amp;#34;, linetype = 3),
        #plot.title.position = &amp;#34;plot&amp;#34;,
        plot.title = element_textbox(face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#AE030E&amp;#34;, size = 14),
        plot.background = element_rect(fill = &amp;#34;#FFF8E7&amp;#34;),
        panel.background = element_rect(fill = &amp;#34;#FFF8E7&amp;#34;),
        plot.margin = margin(20,20,20,20),
        plot.subtitle = element_textbox(face = &amp;#34;bold&amp;#34;),
        plot.caption = element_textbox(face = &amp;#34;italic&amp;#34;, colour = &amp;#34;#4D556B&amp;#34;)) +
    labs(x = &amp;#34;&amp;#34;, y = &amp;#34;% of Year&amp;#34;,
       title = &amp;#34;Percentage of each year where the Billboard No. 1 song &amp;lt;br&amp;gt; prominently contained a saxophone&amp;#34;,
       subtitle = &amp;#34;&amp;#34;,
       caption = &amp;#34;% calculated as total no. 1 weeks in year / 52&amp;#34;) +
    annotate(&amp;#34;segment&amp;#34;, x = as.Date(&amp;#39;2015-01-01&amp;#39;), y = 0.24, xend = as.Date(&amp;#39;2015-01-01&amp;#39;), yend = 0.26, arrow = arrow(type = &amp;#34;closed&amp;#34;, length = unit(0.01, &amp;#34;npc&amp;#34;))) +
    annotate(&amp;#34;text&amp;#34;, x=as.Date(&amp;#39;2015-01-01&amp;#39;),y=0.24, label = &amp;#34;Uptown Funk&amp;#34;, color = &amp;#34;#185AA6&amp;#34;, angle = 0, hjust = 0.5, vjust = 1.5, size = 3, fontface = &amp;#34;bold&amp;#34;) +
    annotate(&amp;#34;segment&amp;#34;, x = as.Date(&amp;#39;1992-01-01&amp;#39;), y = 0.28, xend = as.Date(&amp;#39;1992-01-01&amp;#39;), yend = 0.3, arrow = arrow(type = &amp;#34;closed&amp;#34;, length = unit(0.01, &amp;#34;npc&amp;#34;))) +
    annotate(&amp;#34;text&amp;#34;, x=as.Date(&amp;#39;1992-01-01&amp;#39;),y=0.28, label = &amp;#34;I Will Always Love You&amp;#34;, color = &amp;#34;#185AA6&amp;#34;, angle = 0, hjust = 0.5, vjust = 1.5, size = 3, fontface = &amp;#34;bold&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;You know. The Heights. Angel talking song. 2 weeks at no. 1 in 1992. We all know it.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        
        <item>
            <title>Some Animated Joins</title>
            <link>https://jmablog.com/post/some-animated-joins/</link>
            <pubDate>Sun, 26 Feb 2023 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/some-animated-joins/</guid>
            <description>&lt;p&gt;I spent the weekend picking up the basics of &lt;a href=&#34;https://www.manim.community/&#34;&gt;Manim&lt;/a&gt;, a Python library used for making maths animations - most famously for the YouTube channel &lt;a href=&#34;https://www.3blue1brown.com/&#34;&gt;3Blue1Brown&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In need of something to make, I decided to try and visualise some common SQL joins, as it&amp;rsquo;s something I&amp;rsquo;ve been teaching lately. They&amp;rsquo;ve come out quite nice, so now you get to enjoy them too!&lt;/p&gt;
&lt;h2 id=&#34;inner-join&#34;&gt;Inner join&lt;/h2&gt;


&lt;video width=&#34;100%&#34; loop controls class=&#34;ba bw1 mv3&#34;&gt;
  &lt;source src=&#34;Inner.mp4&#34; type=&#34;video/mp4&#34;&gt;
  &lt;em&gt;Sorry, your browser does not support the video tag.&lt;/em&gt;
&lt;/video&gt;

&lt;h2 id=&#34;left-join&#34;&gt;Left join&lt;/h2&gt;


&lt;video width=&#34;100%&#34; loop controls class=&#34;ba bw1 mv3&#34;&gt;
  &lt;source src=&#34;Left.mp4&#34; type=&#34;video/mp4&#34;&gt;
  &lt;em&gt;Sorry, your browser does not support the video tag.&lt;/em&gt;
&lt;/video&gt;

&lt;h2 id=&#34;outer-join&#34;&gt;Outer join&lt;/h2&gt;


&lt;video width=&#34;100%&#34; loop controls class=&#34;ba bw1 mv3&#34;&gt;
  &lt;source src=&#34;Outer.mp4&#34; type=&#34;video/mp4&#34;&gt;
  &lt;em&gt;Sorry, your browser does not support the video tag.&lt;/em&gt;
&lt;/video&gt;

&lt;h2 id=&#34;but-how-was-manim&#34;&gt;But how was Manim?&lt;/h2&gt;
&lt;p&gt;A very strange mix of &amp;lsquo;incredibly easy&amp;rsquo; and &amp;lsquo;mind-boggling&amp;rsquo;. You can get some basic things up and running surprisingly quickly, but then little things like fonts and colours will be hair-pulling time drains. And I definitely don&amp;rsquo;t think I&amp;rsquo;m using it to the best of its ability here. But overall I recommend it!&lt;/p&gt;
&lt;p&gt;I want to shout out &lt;a href=&#34;https://youtu.be/KHGoFDB-raE&#34;&gt;this video from Brian Amedee&lt;/a&gt; as a good resource for getting to grips with Manim, alongside the main &lt;a href=&#34;https://docs.manim.community&#34;&gt;docs&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id=&#34;can-i-use-these&#34;&gt;Can I use these?&lt;/h2&gt;
&lt;p&gt;Yes! In fact, if you&amp;rsquo;d like any higher-res versions for use in something, please &lt;a href=&#34;mailto:james@jmablog.com&#34;&gt;drop me an email&lt;/a&gt; and I&amp;rsquo;ll be happy to provide. You can also find the (probably poorly optimised) code for these animations on GitHub &lt;a href=&#34;https://github.com/jmablog/manim&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Tinier 0.5.0</title>
            <link>https://jmablog.com/post/tinier-0.5.0/</link>
            <pubDate>Thu, 18 Aug 2022 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/tinier-0.5.0/</guid>
            <description>&lt;p&gt;I had some time on my hands in the last few weeks while I wait to start a new job, so I went back to the &lt;a href=&#34;https://jmablog.github.io/tinieR&#34;&gt;tinieR&lt;/a&gt; package to fiddle around!&lt;/p&gt;
&lt;h2 id=&#34;new-things---petit_plot&#34;&gt;New things - &lt;code&gt;petit_plot&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;d long wanted to find a way to export plots directly from R into pre-tinified image files, and although I&amp;rsquo;d found a way to do it for &lt;a href=&#34;https://ggplot2.tidyverse.org&#34;&gt;ggplot2&lt;/a&gt; plots, doing it with base R plots and devices eluded me.&lt;/p&gt;
&lt;p&gt;Finally I found a (slightly hacky) way of doing it by simply recording the last plot created with &lt;code&gt;recordPlot&lt;/code&gt;, and then replaying it inside the chosen device! One of those things that seems obvious in hindsight, but it works. So, I&amp;rsquo;ve put together two new functions, &lt;code&gt;petit_plot()&lt;/code&gt; and &lt;code&gt;petit_ggplot()&lt;/code&gt; to save and auto-tinify plots!&lt;/p&gt;
&lt;p&gt;You can use most of the same &lt;code&gt;tinify()&lt;/code&gt; options as usual, including keeping the un-tiny image file too, and pass through all regular plotting options to the underlying device too. You can even use &lt;code&gt;petit_plot&lt;/code&gt; with &lt;a href=&#34;https://ragg.r-lib.org/&#34;&gt;ragg&lt;/a&gt; if you have it!&lt;/p&gt;
&lt;p&gt;You can read more in the &lt;a href=&#34;https://jmablog.github.io/tinieR/articles/saving-plots.html&#34;&gt;new &amp;lsquo;saving plots&amp;rsquo; package vignette here&lt;/a&gt;, and here&amp;rsquo;s an example of the new function in action:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;library(tinieR)

p &amp;lt;- ggplot(data = palmerpenguins::penguins,
            aes(flipper_length_mm, body_mass_g)) +
     geom_point(aes(color = species)
     
petit_ggplot(filename = &amp;#34;penguins&amp;#34;, plot = p)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I love tinkering away on this little project. Once again, I&amp;rsquo;m going to really recommend developing a package for getting to know R better. It doesn’t have to do much fancy - tinieR certainly doesn’t - but having problems to solve really gives purpose to your learning. If you want to try it, check out the &lt;a href=&#34;https://r-pkgs.org/&#34;&gt;R Packages book&lt;/a&gt; by Hadley Wickham and Jenny Bryan for a complete guide!&lt;/p&gt;
&lt;p&gt;I hope you’ll try out &lt;a href=&#34;https://jmablog.github.io/tinieR/&#34;&gt;tinieR&lt;/a&gt; for yourself - and if you encounter any issues, &lt;a href=&#34;https://github.com/jmablog/tinieR/issues&#34;&gt;please let me know&lt;/a&gt;!&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>How To Spot Bad Coaching Advice Online</title>
            <link>https://jmablog.com/post/bad-coaching-advice/</link>
            <pubDate>Wed, 09 Mar 2022 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/bad-coaching-advice/</guid>
            <description>&lt;div class=&#34;aside&#34;&gt;
    &lt;p&gt;&lt;em&gt;This post was written in collaboration with John &amp;lsquo;Hedge&amp;rsquo; Hall of &lt;a href=&#34;https://www.accessparkour.com/&#34;&gt;Access Parkour&lt;/a&gt;. You can also find a copy of this post on the &lt;a href=&#34;https://www.accessparkour.com/post/how-to-spot-bad-coaching-advice-online&#34;&gt;Access Parkour blog&lt;/a&gt; and on &lt;a href=&#34;https://www.parkour.earth/articles/how-to-spot-bad-coaching-advice-online&#34;&gt;Parkour Earth&amp;rsquo;s article section&lt;/a&gt;. There are minor formatting differences to fit the style of each site, but otherwise they are all identical.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;As sports coaches, we are endlessly bombarded with different sources of information. Finding our way through this endless stream of opinions and assertions is difficult and it’s not uncommon for coaches to be exposed to the best marketing arguments instead of the most valid ones. Scientific literature is often dense and difficult to understand, and instead we often absorb it via a pop-sci article written by a third party. Which articles are relevant to our needs? Which are useful and which are not? Sometimes, an article is flawed through error or unfamiliarity, and sometimes it’s just a bad take by a good salesman. How do we tell which is which?&lt;/p&gt;
&lt;p&gt;Within this article we want to explore evidence based coaching, it’s limits and how conventional wisdom fits into the picture. We hope that, by the end of this discussion, you’ll at least have a good idea of the reason it can be so difficult to separate fact from fiction and better understand the struggles of a sports coach. Even if, like us, you’ll probably walk away still a little unsure how to deal with it all.&lt;/p&gt;
&lt;h2 id=&#34;sports-science-and-empirical-evidence&#34;&gt;Sports science and empirical evidence&lt;/h2&gt;
&lt;p&gt;It’s been famously claimed that “democracy is the worst form of government, except for all those other forms.” Similar things could be said about the modern sports science approach of controlled experimentation and peer review.&lt;/p&gt;
&lt;p&gt;Modern science works through observation, hypothesis, experiments, and review. A hypothesis is proposed (&lt;em&gt;men in their 30s like to write long winded blog posts&lt;/em&gt;). An experiment is designed (&lt;em&gt;we asked 57 different men of all different ages if they enjoyed producing blog posts over 1000 words&lt;/em&gt;) and then results are analysed (&lt;em&gt;men in their 30s were significantly more likely to report they enjoyed producing blog posts over 1000 words than other age groups&lt;/em&gt;). But the experiment may have structural flaws that aren&amp;rsquo;t exposed until it is compared to many others (&lt;em&gt;it turns out Hedge’s mates aren’t a representative statistical sample of the adult male population as a whole&lt;/em&gt;). This flaw is hopefully spotted when another party takes a look at the study (&lt;em&gt;James peer reviews Hedge’s work and points this out&lt;/em&gt;). If the flaw is spotted, we can update the hypothesis or experiment and try again (&lt;em&gt;ask a whole lot more adult men than just Hedge’s mates&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;The scientific method (mostly) produces information that is true, for the &lt;em&gt;majority&lt;/em&gt; of cases within a &lt;em&gt;defined&lt;/em&gt; population. They are narrow in scope and should be read as such. It’s a feature, not a bug. Make your study too broad, and you risk introducing factors that make it more difficult to determine if the cause and effect link you are looking for is actually present. Famously, shark attacks increase in correlation with ice cream sales, because hotter weather prompts more visits to the beach, not because sharks buy a lot of ice cream.&lt;/p&gt;
&lt;p&gt;So results should be analysed within the context of each experiment and whichever hypothesis prompted the experiment. An individual paper only discusses how valid the evidence is in relation to what is being studied and the method used to study it. Wider meaning may be inferred as an outcome of the results of the study, but this is usually a call for further investigation rather than a statement of truth. Consequently a single paper very rarely provides overwhelming proof and it’s perfectly possible for two valid papers to exist that contain opposing evidence.&lt;/p&gt;
&lt;p&gt;Using this process, nothing can ever be shown to be 100% true. We can only find as many different ways as possible to show that it isn’t &lt;strong&gt;not&lt;/strong&gt; true. The scientific process is messy and complicated and you can rarely read a lot into a specific study unless you are an expert in that particular niche. Even those with scientific training from different disciplines should hesitate before drawing conclusions from a single paper. These things often aren’t settled until sufficient evidence has been compiled, the meta-analysis has been done and then someone in scientific communication comes along and tries to form the body of evidence into a coherent story that is easy for others to digest. This is often how a larger picture is reached: in the aggregate.&lt;/p&gt;
&lt;p&gt;All of this is a way of saying that empirical evidence is good and studies are important, but we should bear in mind that a single study alone is rarely sufficient evidence to change our approach to fitness. While recognising that sports science is absolutely producing important evidence that we, as coaches, should be listening to in order to improve our practice.&lt;/p&gt;
&lt;h2 id=&#34;conventional-wisdom&#34;&gt;Conventional wisdom&lt;/h2&gt;
&lt;p&gt;Conventional wisdom can be thought of as any practice where people using these methods report that it has worked for them. However, either the underlying mechanisms aren’t understood enough to definitively say why it works, or there just isn’t enough evidence yet to call it one way or another. The practice often comes with proposed explanations about how it works and these explanations often lack credible evidence. Usually that evidence is personal, anecdotal experience. People have followed this process and it has worked for them. This is a valid experience but, unfortunately, it is not sufficient evidence that it will work for everyone or that it worked for exactly the reasons claimed.&lt;/p&gt;
&lt;p&gt;Essentially, it’s not disputed that a number of people have had positive wellbeing results from the practice, but the mechanism may be different from what is described. Healing crystals can have really positive effects for a lot of people and astrology horoscopes provide comfort to many. But rocks don’t produce healing fields and stars don’t impact your personality. At the other end of the discussion, no-one is seriously arguing that stretching and mobility isn’t good for you. But we simply aren’t sure about why it works and exactly what it is doing. To compound the matter, two people may have very different results from the same stretching protocol. Massage is another topic where consensus is difficult to find and there are no easy answers, despite the fact that it’s almost universally agreed that massage provides benefits to those on the receiving end of it.&lt;/p&gt;
&lt;p&gt;It’s quite common for these conventional practices to have many integrated parts that form part of a lifestyle. In Ashtanga Yoga, you are getting up earlier, exercising first thing, doing long stretches with specific breathing protocols and it is often associated with changes in diet as well. This is a fairly complex set of lifestyle changes that all occur at once. While the entire practice cumulatively may benefit people, it isn’t a simple matter for a study to be able to understand which parts of this practice are responsible for that.&lt;/p&gt;
&lt;p&gt;As a sports coach, you’ll find there’s a lot more conventional wisdom out there than there are well written scientific op-eds that explain things to you. Especially if you work in a niche sport that isn’t well studied. It’s important to know that the two can co-exist and do not automatically cancel each other out. Scientific papers provide information on the population. Individuals provide information on themselves. If a client presents themselves to you and says that acupuncture really helped with their knee pain before, you can believe them. It does not mean acupuncture is the only thing that will help them and it does not mean you need to start delivering acupuncture to all your clients.&lt;/p&gt;
&lt;p&gt;Unfortunately, you are likely to encounter many instructors with large media followings citing specific studies to back up their conventional wisdom. This can be a double edged sword as they may be experts in the field having deep domain specific discussions, or they may be using marketing gimmicks to appear to be experts. They may even be bad actors actively encouraging you to ignore a scientific consensus that exists against them. Most people likely lack the tools to properly assess the difference between these instructors.&lt;/p&gt;
&lt;h2 id=&#34;spotting-good-advice&#34;&gt;Spotting good advice&lt;/h2&gt;
&lt;p&gt;Inevitably, at some point you are going to find yourself considering whether to trust someone without sufficient evidence backing up their claims. So within this whirling world of difficult to digest evidence, how do we actually decide who we should be trusting?&lt;/p&gt;
&lt;p&gt;There are a few different areas you can focus on if you want to make sure you are following good advice online:&lt;/p&gt;
&lt;div class=&#34;aside&#34;&gt;
    &lt;p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The goals and outcomes of the advice are applicable to you, your clients, or your sport and not just generic advice&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You can see some evidence of successful results that indicate a generally positive, healthy outcome. If anecdotal, you are able to find or verify these success stories from sources independent of the person making the claims&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The instructors&amp;rsquo; clients are fairly diverse and their work is adaptable to many different bodies&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The instructor seems to have a long history in the activity they are promoting and isn’t just jumping into the latest fad&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The instructor rarely gives definitive answers about ‘why’ things are happening, but instead provides education and possibilities, with options to suit a variety of situations&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You can try out and assess the advice for yourself with very low risk and commitment&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Above all, avoid programmes that encourage an ‘all-or-nothing’ attitude. Anything where someone is claiming that this one simple trick fixes everything, or tells you that everyone else is wrong is almost certainly just selling something. We strongly encourage everyone to read widely, discuss openly, and engage with a variety of sources. Be critical but open, analytical but empathetic, discerning but not dismissive. Ultimately, it comes down to your judgement, personal and professional, to consider the evidence and potential risks in any modality you are delivering to a client or patient. But that judgement should absolutely be an &lt;em&gt;informed&lt;/em&gt; one.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Parkour, Perpetual Challenge, and Burnout</title>
            <link>https://jmablog.com/post/parkour-challenge-burnout/</link>
            <pubDate>Sat, 29 Jan 2022 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/parkour-challenge-burnout/</guid>
            <description>&lt;div class=&#34;aside&#34;&gt;
    &lt;p&gt;&lt;em&gt;This post was written and shared as part of &lt;strong&gt;Time To Talk Day 2022&lt;/strong&gt;, an initiative to encourage conversations around mental health. You can check out more on &lt;a href=&#34;https://timetotalkday.co.uk/&#34;&gt;Time To Talk here&lt;/a&gt; and start your own conversations using the tag &lt;strong&gt;#TimeToTalk&lt;/strong&gt; on social media.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I&amp;rsquo;ve been hanging out on the &lt;a href=&#34;https://www.parkour.earth/&#34;&gt;Parkour Earth&lt;/a&gt; Discord for a little while now. ^[Which you can also join here: https://discord.com/invite/aESab8czGw] While there, a conversation came up in the coaching channel about motivation for your own training as a coach, and how it changes after you &lt;em&gt;stop&lt;/em&gt; coaching. In particular, this quote stood out to me:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&amp;rsquo;ve gone through many ups-and-downs over the years in coaching / training but now have a good equilibrium I think. The key was that all-important word - challenge. If you&amp;rsquo;re not challenging yourself while training and just going through movements you can already do, then it just gets boring. I&amp;rsquo;ve found the key to be that I HAVE to do something I&amp;rsquo;ve not before in every session of training and I have to be scared of it. If I&amp;rsquo;m not worried, then I&amp;rsquo;m comfortable - which means I&amp;rsquo;m not going to get much out of it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What was interesting was that my own experience was almost the complete opposite - for one, the impetus of needing to keep in good condition for coaching kept my motivation up, and since stopping coaching  I’ve found it harder to care about my own training as much. But the idea of &amp;lsquo;challenge&amp;rsquo; in a training session is also something I&amp;rsquo;ve been thinking about a fair bit recently. In fact, I&amp;rsquo;ve tried to write a variation on this blog post a number of times and abandoned it, but the conversational nature of the Discord chat finally got me to lay it out in a way I kind of liked. So, I&amp;rsquo;ve taken my replies and expanded on them a bit to put together this post.&lt;/p&gt;
&lt;h2 id=&#34;burnout-and-challenge&#34;&gt;Burnout and challenge&lt;/h2&gt;
&lt;p&gt;Looking back, I think I went through a really intense period of burnout last year (in many aspects of my life, not just training). As a result, I found that the second I encountered meaningful challenge in my training - whether that be psychologically or physically - my body would just shut down, and kill the session dead. The best way I find to describe it is that my &amp;lsquo;spare emotional bandwidth&amp;rsquo; is severely reduced, and things I would normally take in stride or even relish the challenge of instead boil me over into stress and anxiety much quicker. Consequently I&amp;rsquo;ve had to curtail the intensity of my training to the point that my criteria for success for a day will sometimes be as as little as &amp;ldquo;did a single push up&amp;rdquo; or &amp;ldquo;went for a walk&amp;rdquo;. ^[Small side story: the only physical activity I really got into last year was running. Recently, after about 18 months of not doing any strength or resistance training at all, I discovered I couldn&amp;rsquo;t do a single push-up anymore. I decided to commit to doing a minimum of one push-up a day for a while, just to get a bit of strength back. After only a month, I was back up to sets of about 12-15 reps. This is why I like to tell people not to overly worry about taking a break from particular exercises or training in general - you might not retain your strength or fitness completely, but it &lt;em&gt;comes back so much quicker&lt;/em&gt; than it took to get it in the first place.]&lt;/p&gt;
&lt;p&gt;But that in turn has had a very negative interaction with my understanding of what makes a worthwhile training session - that is, it HAS to be hard, or challenging. I would end a training session feeling guilty that I had not pushed myself within it. And that would further fuel an apathy for training over time - what&amp;rsquo;s the point in doing it if I&amp;rsquo;m not dying by the end of every training session, or conquering fears constantly?&lt;/p&gt;
&lt;p&gt;I think it&amp;rsquo;s an attitude that I built up over time because, well, that&amp;rsquo;s the implicit culture of parkour. It&amp;rsquo;s unspoken, but there are often extremely unrealistic standards for the elite physical and mental abilities parkour athletes are expected to have. Those expectations are often not a reasonable level of athleticism for someone to achieve or maintain who is not pursuing the sport full time as a professional or with the dedicated passion of a true devotee. There is also an implicit expectation of constant progression and improvement that is hard to reconcile when you inevitably encounter training plateaus. ^[Not that there&amp;rsquo;s anything wrong with that mindset when you&amp;rsquo;re capable of it - just that it&amp;rsquo;s not realistic to always maintain.] This leads to an environment of perpetual challenge where there is no rest and no finishing line. It&amp;rsquo;s anecdotal but I know SO many people who have either burnt out on the sport or suffered from the same feelings of guilt about not being &amp;lsquo;good enough&amp;rsquo; or training &amp;lsquo;hard enough&amp;rsquo; that I have. I think it is, in short, really hard to just be a hobbyist traceur. ^[For a lot more in-depth look at some of these points, check out Kasturi&amp;rsquo;s (of &lt;a href=&#34;https://espritconcrete.com/&#34;&gt;Esprit Conrete&lt;/a&gt;) PhD thesis: https://repository.londonmet.ac.uk/6852/1/Torchia-Kasturi_DCouPsy-thesis-submission.pdf]&lt;/p&gt;
&lt;h2 id=&#34;identity&#34;&gt;Identity&lt;/h2&gt;
&lt;p&gt;To really pile on the problems, my loss of interest in training and parkour had yet another knock-on effect. As a lifestyle sport, it is very easy for parkour to become the dominant pillar in your life. Up until relatively recently, parkour was my career, hobby, entertainment, and social circle. Even more importantly, it was what I &lt;em&gt;did&lt;/em&gt;, what I &lt;em&gt;was&lt;/em&gt;. Without it, what am I?&lt;/p&gt;
&lt;p&gt;I was still at university at this point, so I couldn&amp;rsquo;t call myself a &amp;lsquo;sports therapist&amp;rsquo; or &amp;lsquo;researcher&amp;rsquo; or &amp;rsquo;lecturer&amp;rsquo; or any of the things I aspired to be yet. &amp;lsquo;Student&amp;rsquo; is itself a transitional term. What was left? I love being a husband, but I didn&amp;rsquo;t want to be a &amp;lsquo;husband&amp;rsquo;. Other hobbies had been crowded out by parkour over the years. I don&amp;rsquo;t mind telling you that I felt truly adrift.&lt;/p&gt;
&lt;p&gt;This phenomena of sudden disassociation with something previously established as a core aspect of an identity is sadly one that can come up in sport, particularly lifestyle sports, a lot. Often it&amp;rsquo;s as a result of an injury - if you can no longer physically play, it can feel like it&amp;rsquo;s been snatched away from you. In my case it was a more gradual fading away, but it left me just as bereft.&lt;/p&gt;
&lt;p&gt;So in very short order I went from burnt out, to apathetic, to bereft of identity. All because I stopped engaging with a single activity. That&amp;rsquo;s a &lt;em&gt;lot&lt;/em&gt;. I may be an extreme case but I know it&amp;rsquo;s happened to others. As a result, I always feel a little pang of worry when I see someone who has the word &amp;lsquo;parkour&amp;rsquo; or &amp;rsquo;traceur&amp;rsquo; in their personal social media handles. It shouldn&amp;rsquo;t be in your name, in your &lt;em&gt;identity.&lt;/em&gt; It feels too&amp;hellip; close.&lt;/p&gt;
&lt;h2 id=&#34;cheer-pressure&#34;&gt;Cheer pressure&lt;/h2&gt;
&lt;p&gt;As a discipline, I don&amp;rsquo;t think we really talk about these potential negative psychological effects (effects that are found in almost any degree of high-level sports performance) and the impact they can have on athletes nearly enough. And I have a couple of theories why. Firstly, we&amp;rsquo;re still striving for acceptance and legitimacy in the eyes of much of the established sporting world, or hell, the world in general. Everyone wants to present parkour in the best possible light, which is great, but it doesn&amp;rsquo;t mean we get to just ignore the downsides.&lt;/p&gt;
&lt;p&gt;In a way, I think we&amp;rsquo;d benefit from coming to terms with the fact that parkour &lt;em&gt;isn&amp;rsquo;t&lt;/em&gt; as special or unique as we&amp;rsquo;ve all sometimes pretended it is. Many of the special things touted for parkour (physical fitness, seeking challenge, facing fear, community) can happily be found in other activities, and just as similarly, many of the downsides of other activities (social pressure, identity, burnout) can be found in parkour. But the relentless act of presenting parkour in the best possible light - even if &lt;em&gt;entirely understandable&lt;/em&gt; in the circumstances - brushes those conversations under a rug.&lt;/p&gt;
&lt;p&gt;Secondly, parkour is still very young-male dominated, a group of people &lt;em&gt;famous&lt;/em&gt; for not being able to talk about their feelings. Discouraged from doing so by society, even! What&amp;rsquo;s worse, I&amp;rsquo;ve seen an increase in the embracing and sharing of a disturbingly &amp;lsquo;man-up&amp;rsquo; approach to training and mental health in some circles, through advocacy for the works of (sigh) Jordan Peterson and his ilk. ^[I won&amp;rsquo;t mince my words, I fucking loathe ol&amp;rsquo; J. Piddles. &lt;a href=&#34;https://www.currentaffairs.org/2018/03/the-intellectual-we-deserve&#34;&gt;Here&amp;rsquo;s a pretty comprehensive break down of his schtick&lt;/a&gt; from 2018, and he&amp;rsquo;s only gotten worse since then.] It&amp;rsquo;s through phrases like &amp;lsquo;anti-fragility&amp;rsquo; and &amp;lsquo;grit&amp;rsquo; that young men who are suffering are led to believe they have somehow &lt;em&gt;failed&lt;/em&gt; at being tough enough rather than experiencing an entirely normal and &lt;em&gt;human&lt;/em&gt; ebb and flow of emotion. The wrapping up of constant risk-facing or fear-conquering, something often understood to be an intrinsic part of parkour, with macho-masculinity is something I&amp;rsquo;ve also wondered about since reading &lt;a href=&#34;https://mandateletter.substack.com/p/masculinity-risky-business&#34;&gt;&amp;ldquo;Masculinity ≠ Risky Business&amp;rdquo;&lt;/a&gt; last year.&lt;/p&gt;
&lt;p&gt;In my opinion, and forgive me for the upcoming &lt;em&gt;very&lt;/em&gt; dramatic sentence, but: it all combines with the perceived assumption of elite-level ability and expectation of perpetual unending challenge inherent in parkour practise to form an environment that is extraordinarily effective at suppressing the honest expression of male anguish, which in turns bleeds out to become the dominant culture of the sport.&lt;/p&gt;
&lt;p&gt;Oh boy. It&amp;rsquo;s sentences like that make me glad I don&amp;rsquo;t have a comment section on these posts.&lt;/p&gt;


&lt;video width=&#34;100%&#34; autoplay loop class=&#34;ba bw1 mv3 max-w-sm block&#34;&gt;
  &lt;source src=&#34;yikes.mp4&#34; type=&#34;video/mp4&#34;&gt;
  &lt;em&gt;Sorry, your browser does not support the video tag.&lt;/em&gt;
&lt;/video&gt;

&lt;p&gt;More broadly, I also think this ties into a lot of the &amp;lsquo;overcoming obstacles&amp;rsquo; aspect of parkour. It is a pretty central tenet of parkour practise to find a challenge, and try and conquer it. This can lead to a very objective, problem-solving mindset, and a tendency to not allow oneself to quit something hard. In theory this is grand, but this narrative overwhelms empathetic discussion of issues; I&amp;rsquo;ve seen pleas for help absolutely subsumed by suggestions for ways to &amp;lsquo;solve the problem&amp;rsquo;, rather than simply providing genuine emotional support. It also smothers the idea that, &lt;em&gt;sometimes&lt;/em&gt;, the right thing to do for your own well-being &lt;strong&gt;is actually to quit&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll say that again: sometimes, the right thing to do is to honestly assess why you feel you should be doing the thing, and to quit the thing if it&amp;rsquo;s making you miserable rather than struggle on out of some feeling of obligation. It&amp;rsquo;s what I did. I made the decision to consciously decouple myself from parkour training, as it was no longer the right thing for me to be doing at that stage of my life. And, let me tell you, finally actively giving myself permission to walk away from that source of stress in my life to focus on other things &lt;em&gt;felt so good&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&#34;talk&#34;&gt;Talk&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s important to emphasise something I mentioned above - these things are mostly &lt;em&gt;implicit&lt;/em&gt; in parkour. It is a &lt;em&gt;side-effect&lt;/em&gt;. Nobody (at least in my experience) is intending to stress out fellow athletes or wilfully looking to turn a blind eye to these issues, particulary in the coaching community. I often as a coach heard, took part in, or initiated conversations about reassuring a student they were doing well or that it&amp;rsquo;s not about comparing themselves to other athletes. ^[For a nice example of the foregrounding of a positive mental approach to parkour training in coaching: see &lt;a href=&#34;https://www.linkedin.com/pulse/serious-fun-how-our-play-becomes-practice-john-hall/?trackingId=HBWMCxkhRqW9%2FSx1BnXV0A%3D%3D&#34;&gt;this blog post&lt;/a&gt; by John &amp;lsquo;Hedge&amp;rsquo; Hall of Access Parkour about their values and mission statement] But there can be quite a big difference between what is &lt;em&gt;said&lt;/em&gt; and how it &lt;em&gt;feels&lt;/em&gt;. And these conversations tend to be aimed at reassuring beginners, &lt;em&gt;not&lt;/em&gt; aimed at providing psychological aid to experienced athletes who are, I expect, simply assumed to be able to cope.&lt;/p&gt;
&lt;p&gt;As a developing sport/discipline, we are in a great position to instead build the psychological well-being of our athletes into the very foundations of our practise. All it takes is being willing to talk about it.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Quarto templates for lecturers and educators</title>
            <link>https://jmablog.com/post/quarto-templates/</link>
            <pubDate>Wed, 26 Jan 2022 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/quarto-templates/</guid>
            <description>&lt;p&gt;&lt;a href=&#34;https://quarto.org/&#34;&gt;Quarto&lt;/a&gt; is a fantastic scientific and technical document publishing tool that I just discovered - it&amp;rsquo;s basically Rmarkdown, but expanded beyond R to become a standalone document processor, whether that be just for markdown or including R, Python, and JavaScript code &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;While looking through the Quarto docs, I realised that it also solves another problem I had when I was lecturing as part of my Masters degree last year - generating multiple file formats from a single input file! I didn&amp;rsquo;t bother blogging about it, but last year I ended up setting up a convoluted &lt;a href=&#34;https://pandoc.org/&#34;&gt;Pandoc&lt;/a&gt; and &lt;a href=&#34;https://heerdebeer.org/Software/markdown/pandocomatic/&#34;&gt;Pandocomatic&lt;/a&gt; workflow to generate PDF, HTML, and Word / Powerpoint files from a single markdown input.&lt;/p&gt;
&lt;p&gt;Why? Well, I believe that providing multiple file formats is better for the student experience, letting them download and use them in a format convenient for them. In particular, a well formatted HTML file is very portable, able to adapt and display nicely on a range of device sizes &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The trouble is, maintaining multiple file formats by hand is a nuisance - you change one thing, and have to update it in three different places. Instead, having a single source of truth - a markdown file, in this case - that the other formats build from is much easier to manage and update.&lt;/p&gt;
&lt;p&gt;So, I went ahead and updated my Pandocomatic workflow to use Quarto, and I couldn&amp;rsquo;t be happier. It&amp;rsquo;s much simpler and more straightforward, requiring a lot less technical setup to use.&lt;/p&gt;
&lt;p&gt;There are two versions of these workflows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/jmablog/simple-worksheets-generator&#34;&gt;Worksheets&lt;/a&gt; - to produce working materials / documents for classes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/jmablog/simple-presentations-generator&#34;&gt;Presentations&lt;/a&gt; - to produce slides for lectures / tutorials&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Full details on how to setup and use these workflows are in the GitHub repos linked above. I deliberately kept them simple in style and substance - while Quarto can produce some really nice documents, I used my own templates to strip everything right back to basics, whilst still looking pleasing and clean. Using my own templates did break a bit of Quarto functionality in my testing, so I&amp;rsquo;ve included my own &lt;a href=&#34;https://www.lua.org/&#34;&gt;lua&lt;/a&gt; filter &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; to re-implement the things I consider essential, as well as a little extra function in the auto-linking of questions and answers in the Worksheets.&lt;/p&gt;
&lt;p&gt;Thanks for reading, I hope these workflows might be even a tiny bit helpful to someone out. &lt;a href=&#34;https://twitter.com/jmablog&#34;&gt;Get in touch&lt;/a&gt; if you’ve got any writing / document processing tips of your own to share!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Seriously, it does so much stuff.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Also, giving a nice range of options for use with screen readers and other accessibility tools through semantic HTML.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://jmablog.com/post/pandoc-filters/&#34;&gt;my blog post on lua filters&lt;/a&gt; for details on how to write your own!&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        
        <item>
            <title>Generating Pretty Instagram Quote Images in R</title>
            <link>https://jmablog.com/post/generating-instagram-quote-images-in-r/</link>
            <pubDate>Tue, 07 Dec 2021 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/generating-instagram-quote-images-in-r/</guid>
            <description>&lt;p&gt;Here&amp;rsquo;s a fun little project I worked on over the weekend. &lt;a href=&#34;https://github.com/jmablog/pretty-instagram-quote-generator&#34;&gt;This script&lt;/a&gt; can take a &lt;code&gt;.tsv&lt;/code&gt; file of quotes/text and their sources, and output pretty Instagram-ready quote images with a splash of random colouring. For example:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;quote-example-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d seen a few people getting onboard the quote-image train on Instagram as a fairly easy way of generating content for the site. And this intrigued me as generating social media content is definitely something I&amp;rsquo;ve, uh, &lt;em&gt;struggled&lt;/em&gt; with since launching &lt;a href=&#34;https://pkc.netlify.app/&#34;&gt;Parkour Clinic&lt;/a&gt;. But, considering I just &lt;a href=&#34;https://jmablog.com/research/mres/&#34;&gt;self-published a 15,000 word paper&lt;/a&gt; (on top of the &lt;a href=&#34;https://jmablog.com/research/pkvs/&#34;&gt;6,500 word paper from last year&lt;/a&gt;) full of juicy parkour quotes, I figured this would be an ideal way for me to get my own content train finally moving.&lt;/p&gt;
&lt;p&gt;The only trouble is, I kind of hate image editing these days? I find it really finicky, and I know what I&amp;rsquo;m like - I&amp;rsquo;ll create twenty images and then decide I don&amp;rsquo;t like the font, and have to create them all over again. So I decided to look into a way of creating them programmatically, and the &lt;a href=&#34;https://docs.ropensci.org/magick/&#34;&gt;magick&lt;/a&gt; package in R can do exactly that.&lt;/p&gt;
&lt;p&gt;Initially I was creating the background colours by hand and just overlaying the text - not that hard to do with magick&amp;rsquo;s &lt;a href=&#34;https://docs.ropensci.org/magick/reference/painting.html&#34;&gt;image annotate&lt;/a&gt; function. But, the fun came when I decided to try and also vary the colours of the background slice and text together in pure code, using &lt;a href=&#34;https://docs.ropensci.org/magick/reference/device.html&#34;&gt;magick::image draw&lt;/a&gt; along with some of R&amp;rsquo;s &lt;a href=&#34;https://rdrr.io/r/#graphics&#34;&gt;base graphics&lt;/a&gt; functions. These were fun to figure out because they felt like something older and less user-friendly than a lot of modern R package functionality, and at the end of it all, left me with a sense of understanding R better, which is always a great outcome to these little side projects.&lt;/p&gt;
&lt;p&gt;I also totally spent &lt;em&gt;ages&lt;/em&gt; figuring out and implementing my own &lt;code&gt;word_wrap&lt;/code&gt; function, that was a bit rubbish, before accidentally discovering there was already one in base R with &lt;code&gt;strwrap&lt;/code&gt;. Oh well. Good to know for the future!&lt;/p&gt;
&lt;p&gt;The result is that, with ten minutes work copying and pasting choice excerpts from my papers into a single &lt;code&gt;quotes.tsv&lt;/code&gt; file, I was able to quickly and easily generate nearly 40 quote images I can drip out on the &lt;a href=&#34;https://www.instagram.com/parkourclinic/&#34;&gt;Parkour Clinic Instagram&lt;/a&gt; over the coming months. Perfect. And if I decide to change some colours or a font, well, it takes about ten seconds to recreate them all. Absolute bliss.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d like to generate your own quotes, you can &lt;a href=&#34;https://github.com/jmablog/pretty-instagram-quote-generator&#34;&gt;download this project from GitHub!&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Using the Expertise of Parkour Coaches to Understand Parkour Movement: The Kong Vault</title>
            <link>https://jmablog.com/research/mres/</link>
            <pubDate>Wed, 22 Sep 2021 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/research/mres/</guid>
            <description>&lt;p&gt;This project was my thesis for my MRes Sport and Exercise Science degree. In the spirit of my &lt;a href=&#34;https://jmablog.com/research/pkvs/&#34;&gt;undergraduate degree&lt;/a&gt;, I decided to also post this online to share my research with the wider parkour community.&lt;/p&gt;
&lt;p&gt;This was a big project, but essentially aimed to talk to parkour coaches to really get a good description and potential model of the kong vault for future use in research. As &amp;ldquo;any quantitative assessment of human movement must be preceded by a measurement and description phase&amp;rdquo; (Winter, 2009), well, this was aiming to fill the description phase.&lt;/p&gt;
&lt;p&gt;While much came of the project, my main takeaway personally is that it is entirely possible to work scientifically within parkour without losing sight of the importance of subjectivity and individuality in the movements. There is also an important point about the differences in experiences with learning parkour movements between male and female athletes in the &lt;a href=&#34;https://jmablog.com/research/mres/read/results-and-discussion.html#future-studies&#34;&gt;&amp;lsquo;Future Studies&amp;rsquo; section&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope sharing this is useful or informative for someone out there, and I&amp;rsquo;m happy to talk further about anything regarding the project, just &lt;a href=&#34;mailto:james@jmablog.com&#34;&gt;get in touch&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Big thank you to all those who took part!&lt;/p&gt;
&lt;h2 id=&#34;read-online&#34;&gt;Read Online&lt;/h2&gt;
&lt;p&gt;&amp;#x1f4d4; &lt;a href=&#34;read/&#34;&gt;Read online in full&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;#x1f4c4; &lt;a href=&#34;http://dx.doi.org/10.13140/RG.2.2.33633.02402&#34;&gt;Download PDF from ResearchGate&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;bonus-materials&#34;&gt;Bonus Materials&lt;/h2&gt;
&lt;p&gt;🗞 &lt;a href=&#34;http://dx.doi.org/10.13140/RG.2.2.25244.41608&#34;&gt;Download poster version from ResearchGate&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;It’s important to know that this work has &lt;strong&gt;not&lt;/strong&gt; been peer reviewed.&lt;/p&gt;
&lt;p&gt;Still, I’m proud of my work and I think my findings are, at the very least, interesting. But, please bear the above in mind as you read and consider the results found—and conclusions drawn from those results—with an appropriately critical eye.&lt;/p&gt;
&lt;h2 id=&#34;data&#34;&gt;Data&lt;/h2&gt;
&lt;p&gt;You can also download the full anonymised interview data I collected if you would like to perform your own analysis. If you do so, please get in touch and let me know what you use it for and what you find.&lt;/p&gt;
&lt;p&gt;⬇ &lt;a href=&#34;https://doi.org/10.6084/m9.figshare.16727314.v1&#34;&gt;Download from Figshare&lt;/a&gt; |  ⬇ &lt;a href=&#34;https://github.com/jmablog/using-the-expertise-of-parkour-coaches&#34;&gt;Download from Github repo&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;abstract&#34;&gt;Abstract&lt;/h2&gt;
&lt;p&gt;Parkour is a discipline in which practitioners (&lt;em&gt;traceurs&lt;/em&gt;) traverse their environment using a variety of movements. Parkour’s decentralised spread and community commitment to diverse practice does not provide easily identifiable definitions or outcome measures for a given movement. This can make it challenging to identify a dependent variable of a parkour movement for study or qualitative assessment. In the absence of objective parkour technique definitions, 15 parkour coaches were interviewed about the performance and goals of a common parkour technique, the kong vault. This sampling of expert knowledge provided a broad yet detailed overview of a movement that can be performed with a high degree of variability within a dynamic range of environments. Subsequent analysis led to the development of a deterministic model intended to assist in the understanding of the kong vault in application to highly individual or situational outcomes, rather than comprehensively prescribing objective performance. The model positions the kong vault as consisting of distinct take-off, obstacle contact, and flight phases, and allows connection to any subsequent landing or movement. Flight is determined by the actions taken during take-off and obstacle contact, with obstacle contact making only moderate changes to an existing projectile arc but expressing a greater change in the angular momentum of the body. The optimal outcome of the kong vault can therefore be considered as achieving a projectile arc and body position that effectively places the traceur in as advantageous position as possible to efficiently and consistently perform a given landing or movement.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;read/&#34;&gt;Continue reading&amp;hellip;&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Mario Kart 64 World Records</title>
            <link>https://jmablog.com/post/mario-kart/</link>
            <pubDate>Sat, 29 May 2021 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/mario-kart/</guid>
            <description>&lt;p&gt;&lt;em&gt;(&lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;Tidy Tuesday&lt;/a&gt; is a project to supply weekly data sets for R users to practice their coding skills on. You can find &lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;full details here&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s been a while since I took part in a Tidy Tuesday, but having not played with any R code for a while I got the urge to create some utterly pointless plots this weekend, so here we are. &lt;a href=&#34;https://github.com/rfordatascience/tidytuesday/blob/master/data/2021/2021-05-25/readme.md&#34;&gt;This week&amp;rsquo;s dataset&lt;/a&gt; is looking at world records in Mario Kart 64, which despite being over two decades old (&lt;a href=&#34;https://imgur.com/gallery/AD84Z6V&#34;&gt;don&amp;rsquo;t let it set in&lt;/a&gt;), is still active in the videogame speedrunning community.&lt;/p&gt;
&lt;p&gt;First up, a ridgeline plot of the density of world record activity per track over the years:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;activity.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d seen ridgeplots quite a lot when browsing &lt;a href=&#34;https://twitter.com/search?q=%23TidyTuesday&#34;&gt;#TidyTuesday&lt;/a&gt; on Twitter so I figured it was about time I gave one a shot myself. I used the &lt;a href=&#34;https://wilkelab.org/ggridges/index.html&#34;&gt;ggridges&lt;/a&gt; package and it was fun to finally have an excuse to try it out! Looking at the plot, it seems like there was a resurgence in world record activity later in the games life - most likely due to more widespread internet access and the growth of the speedrunning scene in general as a result, I imagine.&lt;/p&gt;
&lt;p&gt;Second, a plot showing the total amount of time it would take you to complete all the tracks in Mario Kart 64 at the fastest world record pace each year:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;totals.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;The plot itself isn&amp;rsquo;t the most interesting result (although what happened with shortcuts in 2020? My brief research reveals the possible &lt;a href=&#34;https://kotaku.com/mario-kart-64-speedrunner-sets-new-world-record-by-repe-1846254228&#34;&gt;discovery of a new technique&lt;/a&gt; - maybe it made all the difference!) But, the method to get the fastest time per year for both shortcut and non-shortcut uses was a fun puzzle to solve, and involved some fancy &lt;a href=&#34;https://tidyr.tidyverse.org/reference/index.html#section-pivoting&#34;&gt;pivoting&lt;/a&gt; back and forth alongside the use of tidyr&amp;rsquo;s &lt;a href=&#34;https://tidyr.tidyverse.org/reference/fill.html&#34;&gt;fill function&lt;/a&gt; to flesh out those years where no records were set. See the code for all the steps.&lt;/p&gt;
&lt;p&gt;Speaking of the code, have you noticed the &lt;a href=&#34;https://www.jumpingrivers.com/blog/new-features-r410-pipe-anonymous-functions/&#34;&gt;new native R pipe operator&lt;/a&gt;? I thought I&amp;rsquo;d give it a whirl. &lt;code&gt;|&amp;gt;&lt;/code&gt; is certainly easier and quicker to type than the old &lt;code&gt;%&amp;gt;%&lt;/code&gt; one, although there are one or two bits of functionality missing that mean &lt;code&gt;%&amp;gt;%&lt;/code&gt; probably isn&amp;rsquo;t going away entirely just yet.&lt;/p&gt;
&lt;p&gt;Code (also on &lt;a href=&#34;https://github.com/jmablog/jmablog-code-snippets/blob/master/tidy-tuesday/mariokart.Rmd&#34;&gt;GitHub&lt;/a&gt;):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;library(tidyverse)
library(ggtext)
library(ggridges)

# importing data

tuesdata &amp;lt;- tidytuesdayR::tt_load(2021, week = 22)

drivers &amp;lt;- tuesdata$drivers
records &amp;lt;- tuesdata$records

# activity plot

records |&amp;gt;
  separate(date, into = c(&amp;#34;year&amp;#34;, &amp;#34;month&amp;#34;, &amp;#34;day&amp;#34;), sep = &amp;#34;-&amp;#34;) |&amp;gt;
  filter(shortcut == &amp;#34;No&amp;#34;) |&amp;gt;
  ggplot(aes(x = year, y = track, group = track)) +
  geom_density_ridges(rel_min_height = 0.01, fill = &amp;#34;#F97B64&amp;#34;, alpha = .8) +
  labs(x = &amp;#34;&amp;#34;, y = &amp;#34;&amp;#34;, title = &amp;#34;Mario Kart 64 World Record Activity per Track&amp;#34;,
       subtitle = &amp;#34;Plenty of records set near release, with a slump in activity followed by a surge in the 2010s&amp;#34;) +
  scale_x_discrete(breaks = c(1997, 2009, 2021)) +
  scale_y_discrete(expand = expansion(mult = c(0.01, .12))) +
  theme(legend.position = &amp;#34;none&amp;#34;,
        axis.text.x = element_text(face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#3A5678&amp;#34;),
        axis.text.y = element_text(vjust = 0.3, face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#3A5678&amp;#34;),
        axis.ticks = element_blank(),
        axis.line = element_blank(),
        panel.grid = element_blank(),
        panel.grid.major.y = element_line(size = 0.3, colour = &amp;#34;black&amp;#34;, linetype = 3),
        plot.title.position = &amp;#34;plot&amp;#34;,
        plot.title = element_text(face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#AE030E&amp;#34;, size = 18),
        plot.background = element_rect(fill = &amp;#34;#FFF8E7&amp;#34;),
        panel.background = element_rect(fill = &amp;#34;#FFF8E7&amp;#34;),
        plot.margin = margin(20,20,10,20))

# calculating the total times per year

all &amp;lt;- records |&amp;gt;
  separate(date, into = c(&amp;#34;year&amp;#34;, &amp;#34;month&amp;#34;, &amp;#34;day&amp;#34;), sep = &amp;#34;-&amp;#34;) |&amp;gt;
  filter(type == &amp;#34;Three Lap&amp;#34;) |&amp;gt;
  expand(year, track, shortcut)

fastest &amp;lt;- records |&amp;gt;
  separate(date, into = c(&amp;#34;year&amp;#34;, &amp;#34;month&amp;#34;, &amp;#34;day&amp;#34;), sep = &amp;#34;-&amp;#34;) |&amp;gt;
  filter(type == &amp;#34;Three Lap&amp;#34;) |&amp;gt;
  group_by(year, track, shortcut) |&amp;gt;
  summarise(min = min(time)) |&amp;gt;
  ungroup()

total_times &amp;lt;- all |&amp;gt;
  left_join(fastest) |&amp;gt;
  pivot_wider(names_from = c(&amp;#34;track&amp;#34;, &amp;#34;shortcut&amp;#34;), values_from = &amp;#34;min&amp;#34;) |&amp;gt;
  fill(where(is.double), .direction = &amp;#34;down&amp;#34;) |&amp;gt;
  pivot_longer(-1) |&amp;gt;
  fill(where(is.double), .direction = &amp;#34;down&amp;#34;) |&amp;gt;
  separate(col = &amp;#34;name&amp;#34;, into = c(&amp;#34;track&amp;#34;, &amp;#34;shortcut&amp;#34;), sep = &amp;#34;_&amp;#34;) |&amp;gt;
  group_by(year, shortcut) |&amp;gt;
  summarise(total_time = sum(value)) |&amp;gt;
  ungroup() |&amp;gt;
  mutate(shortcut = factor(shortcut))

# total times plot

total_times |&amp;gt;
  pivot_wider(names_from = &amp;#34;shortcut&amp;#34;, values_from = &amp;#34;total_time&amp;#34;) %&amp;gt;% 
  ggplot(aes(x = year)) +
  geom_linerange(aes(ymin = Yes/60, ymax = No/60), colour = &amp;#34;#4C4A42&amp;#34;, linetype = 3) +
  geom_point(aes(y = No/60), size = 3, colour = &amp;#34;#E03135&amp;#34;) +
  geom_point(aes(y = Yes/60), size = 3, colour = &amp;#34;#185AA6&amp;#34;) +
  labs(x = &amp;#34;&amp;#34;, y = &amp;#34;Minutes&amp;#34;,
       title = &amp;#34;Total time to finish all Mario Kart 64 tracks&amp;lt;br&amp;gt;at world record pace&amp;#34;,
       subtitle = &amp;#34;&amp;lt;span style = &amp;#39;color:#E03135;&amp;#39;&amp;gt;Without&amp;lt;/span&amp;gt; shortcuts vs. &amp;lt;span style = &amp;#39;color:#185AA6;&amp;#39;&amp;gt;with&amp;lt;/span&amp;gt; shortcuts&amp;#34;,
       caption = &amp;#34;World record pace calculated as lowest time per track each year&amp;#34;) +
  expand_limits(x = c(-1, 28), y = c(15, 45)) +
  scale_x_discrete(breaks = seq(1997, 2021, by = 3)) +
  theme(legend.position = &amp;#34;none&amp;#34;,
        axis.text.x = element_text(face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#4D556B&amp;#34;),
        axis.text.y = element_text(face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#4D556B&amp;#34;),
        axis.title.y = element_text(face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#4D556B&amp;#34;),
        axis.line = element_line(colour = &amp;#34;#4D556B&amp;#34;),
        panel.grid = element_blank(),
        plot.title = element_textbox(face = &amp;#34;bold&amp;#34;, colour = &amp;#34;#AE030E&amp;#34;, size = 18),
        plot.background = element_rect(fill = &amp;#34;#FFF8E7&amp;#34;),
        panel.background = element_rect(fill = &amp;#34;#FFF8E7&amp;#34;),
        plot.margin = margin(20,20,20,20),
        plot.subtitle = element_textbox(face = &amp;#34;bold&amp;#34;),
        plot.caption = element_textbox(face = &amp;#34;italic&amp;#34;, colour = &amp;#34;#4D556B&amp;#34;))
&lt;/code&gt;&lt;/pre&gt;</description>
        </item>
        
        <item>
            <title>The Problem with Using Youtube Clips for Posture Analysis</title>
            <link>https://jmablog.com/post/posture-analysis/</link>
            <pubDate>Mon, 26 Apr 2021 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/posture-analysis/</guid>
            <description>&lt;p&gt;There&amp;rsquo;s been a few videos going around the parkour community recently claiming to perform postural and biomechanical analysis on some of the &lt;a href=&#34;https://www.youtube.com/user/StorrorBlog&#34;&gt;Storror&lt;/a&gt; athletes. I have a number of issues with these videos, but mostly, I think the methods used to conduct this kind of &amp;lsquo;analysis&amp;rsquo; are deeply flawed.&lt;/p&gt;
&lt;p&gt;Rather than write a lengthy blog post, I thought it easier to just my thoughts into a video, where I can also actively demonstrate some of the points as I&amp;rsquo;m making them:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube-nocookie.com/embed/qoVLYWOQVzs?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;For what it&amp;rsquo;s worth, I hate the idea of putting this kind of &amp;lsquo;response&amp;rsquo; video out. The last thing I want is a return to the good ol&amp;rsquo; days of internet flame-wars and drama. But, if you&amp;rsquo;re making grand claims in a public forum under the pretense of a scientific approach, I think it&amp;rsquo;s important that you are challenged on those claims when they don&amp;rsquo;t hold up to scrutiny.&lt;/p&gt;
&lt;p&gt;Anyway. &lt;a href=&#34;https://twitter.com/jmablog&#34;&gt;Tweet me&lt;/a&gt; if you want to discuss, I guess.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>tinieR 0.4.1</title>
            <link>https://jmablog.com/post/tinier-0.4.1/</link>
            <pubDate>Fri, 05 Feb 2021 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/tinier-0.4.1/</guid>
            <description>&lt;p&gt;I got really, really bored this week, so I decided to go back to the R package, &lt;strong&gt;&lt;a href=&#34;https://jmablog.github.io/tinieR/&#34;&gt;tinieR&lt;/a&gt;&lt;/strong&gt;, that I released last year (if you haven&amp;rsquo;t seen it before, &lt;strong&gt;&lt;a href=&#34;https://jmablog.github.io/tinieR/&#34;&gt;tinieR&lt;/a&gt;&lt;/strong&gt; shrinks image file sizes using the &lt;a href=&#34;https://tinypng.com&#34;&gt;TinyPNG.com&lt;/a&gt; API). My idle tinkering ended up with a few cool little additions to the package, so I figured it was time for a new release: v0.4.1!&lt;/p&gt;
&lt;div class=&#34;aside&#34;&gt;
    &lt;p&gt;&lt;strong&gt;Why 0.4.1?&lt;/strong&gt; Because I set it all up to be 0.4.0, but then I wasn&amp;rsquo;t entirely happy with some things and kept tinkering, and didn&amp;rsquo;t realise that it wasn&amp;rsquo;t exactly straightforward to change git release/tag options. So .1 it is&amp;hellip;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;new-things&#34;&gt;New things&lt;/h2&gt;
&lt;p&gt;Here are the main additions to the package:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Added ability to set global defaults for &lt;code&gt;tinify()&lt;/code&gt; arguments with &lt;code&gt;tinify_defaults()&lt;/code&gt;. Changes made are printed to the console, and if called without any arguments, prints all current default settings.&lt;/li&gt;
&lt;li&gt;Added new &lt;code&gt;suffix&lt;/code&gt; argument in &lt;code&gt;tinify()&lt;/code&gt; to change the &amp;ldquo;_tiny&amp;rdquo; suffix applied to tinified file names.&lt;/li&gt;
&lt;li&gt;Added new &lt;code&gt;return_path = &amp;quot;proj&amp;quot;&lt;/code&gt; option to &lt;code&gt;return_path&lt;/code&gt; argument in &lt;code&gt;tinify()&lt;/code&gt; to return the path to the newly tinified file relative to the project directory, no matter the current working directory.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can read more in the &lt;a href=&#34;https://jmablog.github.io/tinieR/articles/tinieR.html&#34;&gt;new package vignette here&lt;/a&gt;, and here&amp;rsquo;s an example of the new defaults options in action:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;```{r setup, include=FALSE}
library(tinieR)

tinify_defaults(
	suffix = &amp;#39;resized&amp;#39;,
	quiet = &amp;#39;true&amp;#39;,
	return_path = &amp;#39;rel&amp;#39;,
	resize = list(method = &amp;#39;scale&amp;#39;, width = 100)
)
```

Here is my image:

```{r}
knitr::include_graphics(tinify(&amp;#34;imgs/example.png&amp;#34;))
```
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;useful-things-i-learnt&#34;&gt;Useful things I learnt&lt;/h2&gt;
&lt;p&gt;Aside from being slightly useful, the main reason I work on &lt;strong&gt;tinieR&lt;/strong&gt; is to give me an excuse to poke around in R and learn new things about the language. So what did this latest round of tinkering show me?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tinify_defaults()&lt;/code&gt; really taught me about how to set and retrieve &lt;a href=&#34;https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/options&#34;&gt;options&lt;/a&gt; in R, and in particular, how useful it is that they have a &lt;code&gt;default&lt;/code&gt; argument to fall back on when not set.&lt;/li&gt;
&lt;li&gt;It also taught me more about returning &lt;code&gt;messages&lt;/code&gt; and &lt;code&gt;warnings&lt;/code&gt; in R, how to &lt;a href=&#34;https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/warning&#34;&gt;suppress warnings&lt;/a&gt; when required, and how to use &lt;a href=&#34;https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/conditions&#34;&gt;&lt;code&gt;tryCatch&lt;/code&gt;&lt;/a&gt; to collect errors and supply my own or perform a new action.&lt;/li&gt;
&lt;li&gt;&amp;hellip;And how to deal with storing, setting, and retrieving these default options for use in package tests (using &lt;a href=&#34;https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/on.exit&#34;&gt;&lt;code&gt;on.exit()&lt;/code&gt;&lt;/a&gt; mostly).&lt;/li&gt;
&lt;li&gt;I didn&amp;rsquo;t end up actually using it (yet), but I also found out about the &lt;a href=&#34;https://github.com/r-lib/crayon&#34;&gt;crayon package&lt;/a&gt; for printing coloured text to the R console - fun!&lt;/li&gt;
&lt;li&gt;The new &lt;code&gt;&amp;quot;proj&amp;quot;&lt;/code&gt; setting for &lt;code&gt;return_path&lt;/code&gt; got me familiar with the &lt;a href=&#34;https://rprojroot.r-lib.org/&#34;&gt;rprojroot&lt;/a&gt; package. I&amp;rsquo;d used it before for&amp;hellip; &lt;em&gt;something&lt;/em&gt; that I forget, but it was great to really spend some time poking around in it. It&amp;rsquo;s a very useful package when you need it!&lt;/li&gt;
&lt;li&gt;I wrote my first vignette, and it was interesting to see how the &lt;a href=&#34;https://usethis.r-lib.org/&#34;&gt;usethis package&lt;/a&gt; and my prior experience with Rmarkdown made it exceptionally easy.&lt;/li&gt;
&lt;li&gt;Not directly for the release of 0.4.1, but I also spent some time tinkering with the &lt;a href=&#34;https://pkgdown.r-lib.org&#34;&gt;pkgdown&lt;/a&gt; configuration for the &lt;a href=&#34;https://jmablog.github.io/tinieR/&#34;&gt;package documentation site&lt;/a&gt;. Nothing drastic, just a new theme and some moving around of contents, but good to know!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I really recommend developing a package for getting to know R better. It doesn&amp;rsquo;t have to do much fancy - tinieR certainly doesn&amp;rsquo;t - but having problems to solve really gives purpose to your learning. If you want to try it, check out the &lt;a href=&#34;https://r-pkgs.org/&#34;&gt;R Packages&lt;/a&gt; book by Hadley Wickham and Jenny Bryan for a complete guide!&lt;/p&gt;
&lt;p&gt;I hope you&amp;rsquo;ll try out &lt;strong&gt;&lt;a href=&#34;https://jmablog.github.io/tinieR/&#34;&gt;tinieR&lt;/a&gt;&lt;/strong&gt; for yourself - and if you encounter any issues, please &lt;a href=&#34;https://github.com/jmablog/tinieR/issues&#34;&gt;let me know&lt;/a&gt;!&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Pandoc filters in Bookdown</title>
            <link>https://jmablog.com/post/pandoc-filters/</link>
            <pubDate>Sat, 30 Jan 2021 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/pandoc-filters/</guid>
            <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;tldr:&lt;/strong&gt; I wrote a &lt;a href=&#34;https://pandoc.org/lua-filters.html&#34;&gt;Pandoc Lua filter&lt;/a&gt; to correctly format my Bookdown/Rmarkdown documents no matter the output file. You can see the filter as a &lt;a href=&#34;https://gist.github.com/jmablog/d1d1e1e4907b18a3374ebcc486a2812d&#34;&gt;Github gist here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Apparently I&amp;rsquo;m &lt;a href=&#34;https://jmablog.com/post/bookdown-not-bookout/&#34;&gt;never satisfied&lt;/a&gt; enough to stop &lt;a href=&#34;https://jmablog.com/post/scrivdown/&#34;&gt;futzing around&lt;/a&gt; with &lt;a href=&#34;https://bookdown.org/&#34;&gt;Bookdown&lt;/a&gt;. I&amp;rsquo;ve been twiddling and tweaking settings endlessly to see what kind of documents I can produce and, more importantly, how I can get similar results across a number of formats.&lt;/p&gt;
&lt;p&gt;In the process, I&amp;rsquo;ve fallen over some really useful discoveries. They&amp;rsquo;re usually well-documented discoveries and mostly &lt;em&gt;right there&lt;/em&gt;, out in the open, but for some reason I don&amp;rsquo;t see them talked about much despite their incredible usefulness!&lt;/p&gt;
&lt;p&gt;Among these, number #1 with a &lt;em&gt;bullet&lt;/em&gt; is the use of &lt;a href=&#34;https://pandoc.org/filters.html&#34;&gt;Pandoc&amp;rsquo;s custom filters&lt;/a&gt; to modify your source document. These are &lt;em&gt;amazing&lt;/em&gt;. They&amp;rsquo;re basically ways of changing the output from Pandoc based on some logic, such as the output format. So I thought I&amp;rsquo;d talk about them a little bit here, and explain how I&amp;rsquo;ve put them to good use.&lt;/p&gt;
&lt;h2 id=&#34;pandoc-filters&#34;&gt;Pandoc filters&lt;/h2&gt;
&lt;p&gt;You can use &lt;a href=&#34;https://pandoc.org/filters.html&#34;&gt;JSON manipulation&lt;/a&gt; in any code language you prefer to do this, or &lt;a href=&#34;https://pandoc.org/lua-filters.html&#34;&gt;write the filter in Lua&lt;/a&gt;. I chose to use Lua (despite not &lt;em&gt;knowing&lt;/em&gt; Lua) because Pandoc includes a Lua interpreter embedded in it, so you don&amp;rsquo;t need any external dependencies. Fortunately, some Lua basics weren&amp;rsquo;t too hard to pick up, but please excuse my shoddy Lua coding in the examples given.&lt;/p&gt;
&lt;p&gt;I think a diagram will help explain how filters work with Pandoc. Normally, building your book in Bookdown/Rmarkdown looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;filter-diagram.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;You write all your source docs, Bookdown/R processes all your code to produce plots/tables/etc and compiles all that into one mega-source doc, then ships that over to Pandoc with all your Bookdown options to produce your final output file (pdf/html/what-have-you).&lt;/p&gt;
&lt;p&gt;With a filter, there is an extra step in the middle of the Pandoc circle. Under the hood, Pandoc reads in the input doc (&lt;code&gt;book.Rmd&lt;/code&gt; in our case) and turns it into Pandoc&amp;rsquo;s own interstitial format (an &amp;lsquo;abstract syntax tree&amp;rsquo; or &lt;strong&gt;AST&lt;/strong&gt;). Normally this then gets written straight back out into your desired output format.&lt;/p&gt;
&lt;p&gt;But! With a filter, you get a chance to jump in and apply some logic to the &lt;strong&gt;AST&lt;/strong&gt;, &lt;em&gt;before&lt;/em&gt; it then gets sent over to the writer for the output format.&lt;/p&gt;
&lt;p&gt;So, let&amp;rsquo;s say we wanted to change something in the original source document based on whether we are creating a PDF or HTML document. Using a filter, we can create something this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;filter-diagram-2.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;This gives you a chance to affect elements of your document independent of any input/output foibles, and most usefully, change what output Pandoc&amp;rsquo;s writer will generate based on whatever criteria you define. &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;writing-the-filter&#34;&gt;Writing the filter&lt;/h2&gt;
&lt;p&gt;Writing the filter is not &lt;em&gt;super&lt;/em&gt; complicated, and &lt;a href=&#34;https://pandoc.org/lua-filters.html&#34;&gt;the docs are very comprehensive&lt;/a&gt;, but it can take a second to wrap your head around how it works. Essentially, the filter should consist of a function named for one of the elements of Pandoc&amp;rsquo;s AST. Which is just another way of saying, the elements of your source document.&lt;/p&gt;
&lt;p&gt;So, if you want to affect all the &lt;strong&gt;Strong&lt;/strong&gt; elements of your document, you would write a function named &amp;ldquo;Strong&amp;rdquo; and pass it the element as an argument - &lt;code&gt;Strong(elem)&lt;/code&gt;. Pandoc will &amp;lsquo;walk&amp;rsquo; the AST with your filter, and every time it finds a Strong element &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, apply your filter function to the contents of it (elem).&lt;/p&gt;
&lt;p&gt;The only caveat is that a function must return the same type of element that went into it - so for Strong elements, the function &lt;code&gt;Strong()&lt;/code&gt; must return an &lt;em&gt;Inline&lt;/em&gt; element. Some elements are &lt;em&gt;Block&lt;/em&gt; elements, like entire paragraphs or divs, that must also return a Block.&lt;/p&gt;
&lt;p&gt;This can be a bit finicky but basically, if the element can appear in the middle of a sentence, it&amp;rsquo;s probably an &lt;a href=&#34;https://pandoc.org/lua-filters.html#inline&#34;&gt;Inline&lt;/a&gt;. If the element is a collection of smaller elements, it&amp;rsquo;s probably a &lt;a href=&#34;https://pandoc.org/lua-filters.html#blocks&#34;&gt;Block&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s a practical example. I like to use &lt;a href=&#34;https://pandoc.org/MANUAL.html#extension-fenced_divs&#34;&gt;Pandoc&amp;rsquo;s fenced div syntax&lt;/a&gt; to define little breakout boxes of information in my documents. Here&amp;rsquo;s the syntax in my source Markdown file:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Heading

Some text goes here.

::: notes
Here&amp;#39;s the content of my breakout box.
:::
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pandoc already processes this into HTML, resulting in the following output:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Heading&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;Some text goes here.&amp;lt;/p&amp;gt;
&amp;lt;div class=&amp;#34;notes&amp;#34;&amp;gt;
&amp;lt;p&amp;gt;Here&amp;#39;s the content of my breakout box.&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice how Pandoc has spotted our &amp;rsquo;notes&amp;rsquo; label on the paragraph in the Markdown and automatically applied it as a class to the div in the HTML. With a little CSS, this div then shows as:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;html-breakout.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Great. &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; But, if we want to output our document as anything else, this won&amp;rsquo;t work. Under the hood, Pandoc is still applying the &amp;rsquo;notes&amp;rsquo; label to our element in the AST, but that label doesn&amp;rsquo;t &lt;em&gt;mean&lt;/em&gt; anything to the other output formats. Instead, we can use a filter to add the required information to style these boxes in other output formats, without having to change our input syntax.&lt;/p&gt;
&lt;p&gt;For Word/docx output, Pandoc does let you &lt;a href=&#34;https://pandoc.org/MANUAL.html#output&#34;&gt;apply a custom label&lt;/a&gt; to a fenced div, and will then map that onto a style with the same name in your &lt;a href=&#34;https://bookdown.org/yihui/rmarkdown-cookbook/word-template.html&#34;&gt;Word reference doc&lt;/a&gt;. We could just change our syntax and write our source document like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Heading

Some text goes here.

::: {.notes custom-style=&amp;#34;notes&amp;#34;}
Here&amp;#39;s the content of my breakout box.
:::
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, we&amp;rsquo;re still applying the &amp;lsquo;.notes&amp;rsquo; class in HTML (we have to include a period in front of it now though, as we&amp;rsquo;ve switched to use the bracketed divs syntax) but also declaring a custom-style of &amp;rsquo;notes&amp;rsquo; that, if we have the corresponding style in our Word reference doc, Pandoc will apply to the content of the div.&lt;/p&gt;
&lt;p&gt;This is okay, but it&amp;rsquo;s nowhere near as convenient as the first example&amp;rsquo;s syntax. Why not stick with that, and instead have the filter add in the extra syntax for us instead?&lt;/p&gt;
&lt;p&gt;After all, the whole point of all this effort is to keep the output syntax completely divorced from the input syntax, so you can export to any format you might need at a later time. If I start filling my Markdown with code aimed specifically at Word outputs, it defeats the purpose of using a tool like Pandoc in the first place!&lt;/p&gt;
&lt;p&gt;In the filter file (using the &lt;code&gt;.lua&lt;/code&gt; extension), we can define a function named &lt;code&gt;Div&lt;/code&gt; and pass in our element. In this case, we&amp;rsquo;re passing in everything contained within the div - so a nested series of paragraphs, and within each of those, any inline elements. You could drill down and access those if you needed, but for our purposes, we just want to add an extra attribute to the div:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function Div (elem)
  if FORMAT:match &amp;#39;docx&amp;#39; then
    if elem.classes[1] == &amp;#34;notes&amp;#34; then
      elem.attributes[&amp;#39;custom-style&amp;#39;] = &amp;#39;Notes&amp;#39;
      return elem
    else
      return elem
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;FORMAT&lt;/code&gt; is a global variable in a filter that just contains the output format currently being generated. Here, all we&amp;rsquo;re saying is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If the output is docx, look at each div within the document.&lt;/li&gt;
&lt;li&gt;For each div, see if it has the class &amp;rsquo;notes&amp;rsquo; with &lt;code&gt;elem.classes[1]&lt;/code&gt;. &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;If a div has the class &amp;rsquo;notes&amp;rsquo;, then &lt;em&gt;also&lt;/em&gt; add a new attribute named &amp;lsquo;custom-style&amp;rsquo; with the content &amp;lsquo;Notes&amp;rsquo; and return the new div.&lt;/li&gt;
&lt;li&gt;Otherwise, just return the original div.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, provided we have the style &amp;lsquo;Notes&amp;rsquo; setup in our Word reference doc, it will automatically get assigned to our div in the output!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;word-breakout.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Importantly, if we switch our output back to HTML, it makes no difference - the class is just applied to the div as before, and the filter skips over the function as &lt;code&gt;FORMAT&lt;/code&gt; doesn&amp;rsquo;t match docx.&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s also look at PDF output. Pandoc uses LaTeX as an intermediary to generate PDF files. Unfortunately there&amp;rsquo;s no way (I know of) to apply custom styling to LaTeX output natively in Pandoc that doesn&amp;rsquo;t involve just filling your source doc with actual LaTeX. At which point you might as well just&amp;hellip; write LaTeX. Instead, we can use a filter to find our notes div as before, and &lt;em&gt;wrap&lt;/em&gt; some custom LaTeX commands around the div contents instead.&lt;/p&gt;
&lt;p&gt;I used the LaTeX package &lt;a href=&#34;https://www.ctan.org/pkg/tcolorbox&#34;&gt;tcolorbox&lt;/a&gt; for this. The precise mechanisms of tcolorbox aren&amp;rsquo;t the main point here, but if you want to use it exactly as I have you&amp;rsquo;ll need to customise the LaTeX template to include tcolorbox as a package. Easiest way I found was to just put &lt;code&gt;\usepackage{tcolorbox}&lt;/code&gt; in the LaTeX preamble &lt;a href=&#34;https://bookdown.org/yihui/rmarkdown-cookbook/latex-preamble.html&#34;&gt;as detailed here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also use some dvipsnames colour names in the code from &lt;a href=&#34;https://www.ctan.org/pkg/xcolor&#34;&gt;xcolor&lt;/a&gt; with &lt;code&gt;\usepackage[dvipsnames]{xcolor}&lt;/code&gt; so I can create shades of colours, but having recently stumbled over &lt;a href=&#34;https://www.overleaf.com/learn/latex/Using_colours_in_LaTeX#Creating_your_own_colours&#34;&gt;defining your own colours in LaTeX&lt;/a&gt; I might just swap these out for some good ol&amp;rsquo; RGB values in the future. Hey, have you heard of the colour &lt;a href=&#34;https://en.wikipedia.org/wiki/Cosmic_latte&#34;&gt;&amp;lsquo;Cosmic Latte&amp;rsquo;&lt;/a&gt;? (Thanks, &lt;a href=&#34;https://society.robinsloan.com/archive/colophon/&#34;&gt;Robin Sloan&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Anyway.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the filter code:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function Div (elem)
  if FORMAT:match &amp;#39;latex&amp;#39; then
    if elem.classes[1] == &amp;#34;notes&amp;#34; then
      return {
        pandoc.RawBlock(&amp;#39;latex&amp;#39;, &amp;#39;\\begin{tcolorbox}[colframe=Apricot!20!white, colback=Apricot!8!white]&amp;#39;),
        elem,
        pandoc.RawBlock(&amp;#39;latex&amp;#39;, &amp;#39;\\end{tcolorbox}&amp;#39;)
      }
    else
      return elem
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This works much like the Word filter:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If the output is LaTeX, look at each div in the document.&lt;/li&gt;
&lt;li&gt;See if each div has the class &amp;rsquo;notes&amp;rsquo;.&lt;/li&gt;
&lt;li&gt;If it does, create and return a &lt;em&gt;new&lt;/em&gt; Block element.
&lt;ul&gt;
&lt;li&gt;This Block element will contain some raw LaTeX code, followed by the entire original div itself (elem), followed again by some more raw LaTeX.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Otherwise, return the original div.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;pandoc.RawBlock&lt;/code&gt; is what allows us to write some raw code in the language our output format uses - in this case, LaTeX. So the function basically ends up wrapping a &lt;code&gt;\begin{tcolorbox}&lt;/code&gt; and &lt;code&gt;\end{tcolorbox}&lt;/code&gt; around our div and, when output to PDF, the div is now surrounded by the LaTeX code required to create a coloured box!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;pdf-breakout.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;And again, if we switch back to HTML, Pandoc just ignores this function and our output looks the same as before.&lt;/p&gt;
&lt;p&gt;We can combine these two functions into one:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function Div (elem)
  if FORMAT:match &amp;#39;docx&amp;#39; then
    if elem.classes[1] == &amp;#34;notes&amp;#34; then
      elem.attributes[&amp;#39;custom-style&amp;#39;] = &amp;#39;Notes&amp;#39;
      return elem
    else
      return elem
    end
  elseif FORMAT:match &amp;#39;latex&amp;#39; then
    if elem.classes[1] == &amp;#34;notes&amp;#34; then
      return {
        pandoc.RawBlock(&amp;#39;latex&amp;#39;, &amp;#39;\\begin{tcolorbox}[beforeafter skip=1cm, ignore nobreak=true, breakable, colframe=Apricot!20!white, colback=Apricot!8!white, boxsep=2mm, arc=0mm, boxrule=0.5mm]&amp;#39;),
        elem,
        pandoc.RawBlock(&amp;#39;latex&amp;#39;, &amp;#39;\\end{tcolorbox}&amp;#39;)
      }
    else
      return elem
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(&lt;a href=&#34;https://gist.github.com/jmablog/d1d1e1e4907b18a3374ebcc486a2812d&#34;&gt;GitHub Gist&lt;/a&gt;)&lt;/p&gt;
&lt;div class=&#34;aside&#34;&gt;
    &lt;p&gt;I&amp;rsquo;ve since thought of a more streamlined way of doing this that doesn&amp;rsquo;t involve writing an &amp;lsquo;if&amp;rsquo; statement for each type of box you&amp;rsquo;d like to create - see the &lt;a href=&#34;#edit-another-method&#34;&gt;edit at the end of this post&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now we can use fenced divs with &lt;code&gt;::: notes&lt;/code&gt; with abandon in our original Markdown doc, and not worry about how it&amp;rsquo;s going to come out in our output format - no matter which we choose, it&amp;rsquo;ll be formatted as a coloured box.&lt;/p&gt;
&lt;h2 id=&#34;using-with-bookdownrmarkdown&#34;&gt;Using with Bookdown/Rmarkdown&lt;/h2&gt;
&lt;p&gt;To use the filter with Bookdown/Rmarkdown, save it as a &lt;code&gt;.lua&lt;/code&gt; file and place it somewhere convenient within your Bookdown project. I use &lt;code&gt;filters/shortcodes.lua&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The most straightforward way I found to use the filter was to just tell Pandoc about it directly when we issue the command to build our document. In your &lt;code&gt;_output.yml&lt;/code&gt;, just &lt;a href=&#34;https://bookdown.org/yihui/rmarkdown/html-document.html#pandoc-arguments&#34;&gt;pass the filter as an extra argument to Pandoc&lt;/a&gt; using &lt;code&gt;pandoc_args&lt;/code&gt; and &lt;code&gt;--lua-filter&lt;/code&gt;. &lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; You&amp;rsquo;ll need to include it for each output you want:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;bookdown::pdf_document2:
	toc: false
	pandoc_args: [&amp;#34;--lua-filter&amp;#34;, &amp;#34;filters/shortcodes.lua&amp;#34;]
bookdown::word_document2:
	reference_docx: &amp;#34;assets/ref-doc.docx&amp;#34;
	pandoc_args: [&amp;#34;--lua-filter&amp;#34;, &amp;#34;filters/shortcodes.lua&amp;#34;]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Obviously you&amp;rsquo;ll also need to modify any of the surrounding files affected - maybe &lt;a href=&#34;https://bookdown.org/yihui/rmarkdown-cookbook/html-css.html&#34;&gt;some custom CSS&lt;/a&gt;, or the &lt;a href=&#34;https://bookdown.org/yihui/rmarkdown-cookbook/word-template.html&#34;&gt;Word reference doc&lt;/a&gt;, or the &lt;a href=&#34;https://bookdown.org/yihui/rmarkdown-cookbook/latex-preamble.html&#34;&gt;LaTeX template&lt;/a&gt;. &lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Once you get the hang of these filters, you can easily start applying all sorts of custom styling to your outputs from these fenced divs. You could very quickly add mores fenced div to this example - say, &lt;code&gt;::: warning&lt;/code&gt;, that produces red styled boxes. That&amp;rsquo;s on you though as this post has gone on long enough!&lt;/p&gt;
&lt;p&gt;Thanks for reading, I hope it&amp;rsquo;s been even a tiny bit helpful. &lt;a href=&#34;https://twitter.com/jmablog&#34;&gt;Get in touch&lt;/a&gt; if you’ve got any Pandoc/Bookdown tips of your own to share!&lt;/p&gt;
&lt;h2 id=&#34;edit-another-method&#34;&gt;Edit: Another method&lt;/h2&gt;
&lt;p&gt;Since writing this post, I&amp;rsquo;ve also realised another way of applying these filters that doesn&amp;rsquo;t involve writing endless &amp;lsquo;if&amp;rsquo; statements in your filter. Here&amp;rsquo;s the new function:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function Div (elem)
  if FORMAT:match &amp;#39;docx&amp;#39; then
    if elem.classes[1] then
      elem.attributes[&amp;#39;custom-style&amp;#39;] = elem.classes[1]
      return elem
    else
      return elem
    end
  elseif FORMAT:match &amp;#39;latex&amp;#39; then
    if elem.classes[1] then
      local box = &amp;#34;\\begin{tcolorbox}[colframe=&amp;#34; .. elem.classes[1] .. &amp;#34;-frame, colback=&amp;#34; .. elem.classes[1] .. &amp;#34;-bg]&amp;#34;
      return{
        pandoc.RawBlock(&amp;#39;latex&amp;#39;, box),
        elem,
        pandoc.RawBlock(&amp;#39;latex&amp;#39;, &amp;#39;\\end{tcolorbox}&amp;#39;)
      }
    else
      return elem
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It&amp;rsquo;s not that different, but instead of explicitly assigning custom-styles in the docx we just apply &lt;code&gt;elem.classes[1]&lt;/code&gt; directly. As before, as long as your Word reference doc contains a style named the same as the div you create, it&amp;rsquo;ll map over just fine. But this way, you can just create the styles in your Word reference doc and start applying them in your Markdown without having to touch the filter.&lt;/p&gt;
&lt;p&gt;For PDF/LaTeX, the function now creates a string (with the extremely weird Lua string concatenation operator &lt;code&gt;..&lt;/code&gt;) that sets the colours in tcolorbox to a name matching the div name, with &amp;lsquo;-bg&amp;rsquo; and &amp;lsquo;-frame&amp;rsquo; appended to distinguish box background and border colours. The idea is similar - you can now just create the colours in your LaTeX template/preamble and start applying them in your Markdown without having to touch the filter, like so:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;\definecolor{notes-bg}{RGB}{255, 248, 231}
\definecolor{notes-frame}{RGB}{255, 248, 231}
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;aside&#34;&gt;
    &lt;p&gt;Or, you could always take out the &amp;lsquo;-bg&amp;rsquo; and &amp;lsquo;-frame&amp;rsquo; bits, and just give your divs the same names as some of the &lt;a href=&#34;https://www.overleaf.com/learn/latex/Using_colours_in_LaTeX#Reference_guide&#34;&gt;colour names LaTeX has built in&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;These changes mean you can basically just leave the filter alone and create your styles/colours elsewhere to incorporate them, just as with the HTML/CSS output.&lt;/p&gt;
&lt;p&gt;Just be a little careful, as this will apply to all divs in Pandoc - so if you&amp;rsquo;re creating a PowerPoint presentation for example, and you use the &lt;code&gt;::: incremental&lt;/code&gt; div to create incremental bullet points in your slides, then this filter will also try and apply the styles/colours &amp;lsquo;incremental&amp;rsquo; to your output docs in Word/PDF formats. Word will just ignore any styles it doesn&amp;rsquo;t find in your reference doc, but this can stall PDF creation completely, so be ready to work round it or go back to the original &lt;code&gt;elem.classes[1] == &#39;notes&#39;&lt;/code&gt; method in the filter.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;You might have already used one of these without realising - Rmarkdown &lt;a href=&#34;https://rmarkdown.rstudio.com/docs/articles/lua-filters.html&#34;&gt;uses a Pandoc filter&lt;/a&gt; to let you use the LaTeX command &lt;code&gt;\newpage&lt;/code&gt; in your Markdown to force a page-break, even if your output format isn&amp;rsquo;t LaTeX/PDF. If you look, you can spot it in the command line arguments sent over to Pandoc when you build your book.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Don&amp;rsquo;t forget this is in the AST, &lt;em&gt;after&lt;/em&gt; Pandoc has read in and translated your source doc. So it doesn&amp;rsquo;t matter if the source was Markdown defined with &lt;code&gt;**asterisks**&lt;/code&gt;, or HTML defined with &lt;code&gt;&amp;lt;strong&amp;gt;tags&amp;lt;/strong&amp;gt;&lt;/code&gt;. At this point, it&amp;rsquo;s all just &lt;code&gt;Pandoc.Strong&lt;/code&gt; in the AST.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;If you noticed and wondered - I used &lt;code&gt;::before&lt;/code&gt; to add the text &amp;lsquo;Notes:&amp;rsquo; in front of the first paragraph within each div with the class &amp;rsquo;notes&amp;rsquo;. Custom CSS styling for your output is also bonkers-crazy-useful, but that&amp;rsquo;s another post.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Pandoc will have already assigned it to our div from the fenced div syntax without us needing to do anything extra.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;If you want to get really fancy, you could create a custom Rmarkdown format to knit to that includes the filter by default - &lt;a href=&#34;https://rmarkdown.rstudio.com/docs/articles/lua-filters.html#using-filters-with-output-format-1&#34;&gt;see here for more&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;I haven&amp;rsquo;t tried this with &lt;code&gt;gitbook&lt;/code&gt; output yet, but in theory you can just inject the CSS for the breakout box into that and it should work fine.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        
        <item>
            <title>Scrivdown</title>
            <link>https://jmablog.com/post/scrivdown/</link>
            <pubDate>Sat, 12 Dec 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/scrivdown/</guid>
            <description>&lt;p&gt;In my &lt;a href=&#34;https://jmablog.com/post/bookdown-not-bookout/&#34;&gt;last post&lt;/a&gt; on Bookdown, I mentioned using writing environments other than &lt;a href=&#34;https://rstudio.com/&#34;&gt;RStudio&lt;/a&gt; to work on non-code text sections. As I recommended in that post, I&amp;rsquo;ve been using &lt;a href=&#34;https://ia.net/writer&#34;&gt;iA Writer&lt;/a&gt; as my main text editor. It&amp;rsquo;s a great plain editor - I&amp;rsquo;m using it to write this post now. But, as my last big writing project got bigger, and bigger &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, I found myself missing a lot of the writing project management tools from my previous preferred writing app - &lt;a href=&#34;https://www.literatureandlatte.com/scrivener/overview&#34;&gt;Scrivener&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In particular, I missed the ability to segment my work into an outline structure. I initially tried having separate plain text files to break up the text into sections to work on, but although Bookdown would stitch these back together into one final piece fine, they weren&amp;rsquo;t easy to work with. In particular, Bookdown reassembles these files in the order they are listed in the directory, so I ended up numbering all my files (01-intro.Rmd, 02-litreview.Rmd, 03-method.Rmd, etc). But, in Scrivener I would often work as small as the &lt;em&gt;paragraph&lt;/em&gt; level, dragging and dropping chunks of text around to see what flowed best in the overall document. This just wasn&amp;rsquo;t practical in plain text files, as I&amp;rsquo;d have to re-number everything if I wanted to insert something between two existing files, or just live with cutting and pasting paragraphs within docs. Not the end of the world, but just not as &lt;em&gt;easy&lt;/em&gt; as Scrivener.&lt;/p&gt;
&lt;p&gt;So I wanted to move back to Scrivener, but I wanted to keep all the benefits of Bookdown - namely, having my R code included in the document to produce plots/tables, rather than importing images or copying/pasting tables into Scrivener each time I iterated on my code. I also wanted to keep the benefits of compiling to PDF with LaTeX, like auto-generated tables of contents and lists of figures/tables.&lt;/p&gt;
&lt;p&gt;I basically wanted to use Scrivener as my plain text editor. And it turns out, that&amp;rsquo;s actually pretty &lt;em&gt;easy&lt;/em&gt;, but not necessarily &lt;em&gt;straightforward&lt;/em&gt;. Here&amp;rsquo;s how I set it up.&lt;/p&gt;
&lt;h2 id=&#34;inspiration&#34;&gt;Inspiration&lt;/h2&gt;
&lt;p&gt;The idea for this workflow was heavily inspired by &lt;a href=&#34;https://github.com/iandol/scrivomatic&#34;&gt;Scrivomatic&lt;/a&gt;, by Ian Max Andolina. Scrivomatic is great, and I used it extensively in the past, but it doesn&amp;rsquo;t deal with R code. This is the main difference to my setup; the additional layer of R and Bookdown, which also results in a simpler Scrivener setup as things like front-matter yaml code remain in Bookdown itself.&lt;/p&gt;
&lt;p&gt;There are some other useful hints in the Scrivomatic docs worth looking at, like &lt;a href=&#34;https://github.com/iandol/scrivomatic#how-to-use-custom-styles-in-word-and-html&#34;&gt;this tip&lt;/a&gt; on using custom styles when exporting to Word. It&amp;rsquo;s definitely worth checking Scrivomatic out if you like the idea of this kind of workflow and don&amp;rsquo;t need the additional step of including R code when compiling your document.&lt;/p&gt;
&lt;h2 id=&#34;scrivener-setup&#34;&gt;Scrivener setup&lt;/h2&gt;
&lt;p&gt;The nice thing about Scrivener is that you can set up your &lt;em&gt;writing&lt;/em&gt; preferences in it, then tell Scrivener how much of that to keep or discard when it comes time to export your document to the final file format. So, you can set up your internal Scrivener editor pretty much as you like - fonts, colours, styles, whatever makes writing easiest for you. As we&amp;rsquo;re compiling to plain text, all that will be stripped out of the final export, but it can be useful for editing (I like to 
&lt;span class=&#34;bg-yellow-200 dark:text-black px-2&#34;&gt;highlight&lt;/span&gt; bits I need to work on, for example).&lt;/p&gt;
&lt;p&gt;The main thing you need for your project is in the menu &lt;code&gt;Project &amp;gt; Project Settings... &amp;gt; Section Types&lt;/code&gt;. Here, I suggest just having &lt;code&gt;Heading&lt;/code&gt; and &lt;code&gt;Text&lt;/code&gt; sections setup, and under &lt;code&gt;Default Types by Structure&lt;/code&gt;, setting all folders to &lt;code&gt;Heading&lt;/code&gt; and files to &lt;code&gt;Text&lt;/code&gt;. Then, you can setup your project in your binder with folders for each heading, nested folders for sub-headings, and files within these containing your actual text.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;01-sectiontypes.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Because Scrivener can auto-detect heading levels from the Binder structure, then top-level folders will be H1s (&lt;code&gt;# Heading&lt;/code&gt;), sub-folders will be H2s (&lt;code&gt;## Heading&lt;/code&gt;), and so on.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;04-binder.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then, in the &lt;code&gt;File &amp;gt; Compile&lt;/code&gt; menu, set the &lt;code&gt;Compile for&lt;/code&gt; dropdown at the top to &lt;code&gt;MultiMarkdown&lt;/code&gt;. You should set up your own custom compile format - in the left of the window,  right-click &lt;code&gt;Basic MultiMarkdown&lt;/code&gt; and choose &lt;code&gt;Duplicate &amp;amp; Edit Format&lt;/code&gt;. This will open the compile format editing menu &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. Give your new format a name, and choose to save it either into the project - so it will travel around with the actual &lt;code&gt;.scriv&lt;/code&gt; file you&amp;rsquo;re working on - or globally, so it will be available in Scrivener no matter which project you open. I like to save a generic global version, then duplicate that into each project that I can fine-tune to that individual project if required.&lt;/p&gt;
&lt;p&gt;In the format editor, click &lt;code&gt;Section Layouts&lt;/code&gt;, then click the little gear settings icon in the top right. Make sure to untick &lt;code&gt;Add closing hashes to titles&lt;/code&gt;. By default, Scrivener puts markdown headings as &lt;code&gt;# Heading #&lt;/code&gt;, and this option will turn them into just &lt;code&gt;# Heading&lt;/code&gt;. This allows you to put additional Bookdown header options, like &lt;code&gt;{-}&lt;/code&gt; to create an unnumbered heading, in your folder names/headings.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;02-sectionlayoutsoptions.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;If you like to use styles in your Scrivener editor while writing, then while still in the format editor, click &lt;code&gt;MultiMarkdown Options&lt;/code&gt;, then set all the dropdown options here to &lt;code&gt;None&lt;/code&gt;. This stops Scrivener from formatting our output based on internal Scrivener styles you might use - for example, by default it indents any text marked with the &lt;code&gt;Code block&lt;/code&gt; style in the output. I found it easier to just switch these off, but you can experiment with them if you like.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;03-mmdoptions.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;You can play with some of the other settings in the compile format editor too. Most of it is fine as default, but you might like to explore it more. Make a note of the &lt;code&gt;Processing&lt;/code&gt; section - we&amp;rsquo;ll come back to this later. Otherwise, just click &lt;code&gt;Save&lt;/code&gt; to save your new compile format.&lt;/p&gt;
&lt;p&gt;Back in the compile menu, you can make sure all the headings/text you want to compile are selected on the right, and that they&amp;rsquo;ve all been assigned the correct section layout. If you get a yellow box in the middle saying your layouts haven&amp;rsquo;t been assigned to a section type, just click &lt;code&gt;Assign Section Layouts&lt;/code&gt; at the bottom and make sure &lt;code&gt;Heading&lt;/code&gt; is set to &lt;code&gt;Heading&lt;/code&gt;, and &lt;code&gt;Text&lt;/code&gt; is set to &lt;code&gt;Text Section&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Click the little tag icon in the top right of the compile menu, and delete any metadata fields listed here by clicking the row in the &lt;code&gt;key&lt;/code&gt; box, then clicking the minus sign at the bottom of the menu. If the default metadata is left in, Scrivener will insert it as yaml at the top of the exported file. It won&amp;rsquo;t break anything, but as we&amp;rsquo;re using Bookdown for all our metadata, it&amp;rsquo;s unnecessary to include it again.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;05-metadata.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Finally, click the cog icon in the top right of the compile menu, and tick &lt;code&gt;Convert rich text to MultiMarkdown&lt;/code&gt;. This lets you use visual WYSIWYG styling like italics and bold in the editor, and Scrivener will automatically put markdown formatting around it on export. Then, untick &lt;code&gt;Escape special characters&lt;/code&gt;, otherwise Scrivener will escape out the code chunks we write later. The other options here can remain as default, but you can experiment with them if you feel confident.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;06-richtexttommd.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s it for Scrivener setup - you can then click &lt;code&gt;Compile&lt;/code&gt; to export your plain text file. Scrivener will default to &lt;code&gt;file.md&lt;/code&gt; as a file extension, but you can actually just type &lt;code&gt;file.Rmd&lt;/code&gt; in the save dialogue for your filename to export to &lt;code&gt;.Rmd&lt;/code&gt; - you&amp;rsquo;ll get a pop-up warning but just click the option that lets you use a custom file extension. You can check the output looks how you want - it should basically just resemble any other Rmarkdown file, as if you&amp;rsquo;d written it straight in RStudio.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;07-rmdextension.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;So that&amp;rsquo;s Scrivener setup - what about R and Bookdown?&lt;/p&gt;
&lt;h2 id=&#34;r--bookdown-setup&#34;&gt;R / Bookdown setup&lt;/h2&gt;
&lt;p&gt;On the R side of things, you can basically setup a Bookdown project as normal - so project creation, &lt;code&gt;index.Rmd&lt;/code&gt; setup, &lt;code&gt;_bookdown.yml&lt;/code&gt; and &lt;code&gt;_output.yml&lt;/code&gt;, all that stuff, remains the same. If you&amp;rsquo;re unclear on any of that, the &lt;a href=&#34;https://bookdown.org/yihui/bookdown/&#34;&gt;Bookdown manual&lt;/a&gt; is the best place to start.&lt;/p&gt;
&lt;p&gt;The main thing is to make sure you&amp;rsquo;ve set up Bookdown to find the file you&amp;rsquo;re exporting from Scrivener - I usually have a subdirectory like &lt;code&gt;book/src&lt;/code&gt; that I then direct &lt;code&gt;_bookdown.yml&lt;/code&gt; to find with &lt;code&gt;rmd_subdir = &amp;quot;book/src&amp;quot;&lt;/code&gt;, and then export from Scrivener into that directory. There&amp;rsquo;s a bit more detail on that in the manual specifically &lt;a href=&#34;https://bookdown.org/yihui/bookdown/configuration.html&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The main difference is that code isn&amp;rsquo;t going to be written &lt;em&gt;directly&lt;/em&gt; into your Rmarkdown text in Scrivener - instead, code is written and worked on in separate &lt;code&gt;.R&lt;/code&gt; script files. &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; I like to store mine in another directory (I use an &lt;code&gt;analysis&lt;/code&gt; folder in the Bookdown project directory). These can be worked on in Rstudio in the normal way. But, although the code will be written in &lt;code&gt;.R&lt;/code&gt; files, rather than &lt;code&gt;.Rmd&lt;/code&gt;, we&amp;rsquo;re still going to divide the code up into &lt;a href=&#34;https://yihui.org/knitr/demo/externalization/&#34;&gt;Knitr&lt;/a&gt; chunks using the following syntax:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## ---- example-table

mtcars %&amp;gt;%
  head(3) %&amp;gt;%
  kable(caption = &amp;#34;Example table with a long caption.&amp;#34;,
      caption.short = &amp;#34;Short caption.&amp;#34;,
      booktabs = T)
      
## ---- example-plot

mtcars %&amp;gt;%
  ggplot(aes(drat, wt)) +
  geom_point()
  
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Knitr chunks in &lt;code&gt;.R&lt;/code&gt; files are a bit strange, and don&amp;rsquo;t look like they do in &lt;code&gt;.Rmd&lt;/code&gt; files, but basically boil down to two hashes and at least four dashes, followed by a chunk name: &lt;code&gt;## ---- chunk-name&lt;/code&gt;. Make sure not to have any spaces in the chunk name. It&amp;rsquo;s a little unclear, but a chunk will basically include everything up to the next chunk header.&lt;/p&gt;
&lt;div class=&#34;aside&#34;&gt;
    &lt;p&gt;&lt;strong&gt;Aside:&lt;/strong&gt; I got curious about this syntax change and it led me down a rabbit hole of &lt;a href=&#34;https://en.wikipedia.org/wiki/Literate_programming&#34;&gt;literate programming&lt;/a&gt; history, with a lot of this stuff seemingly coming from places like &lt;a href=&#34;https://www.cs.tufts.edu/~nr/noweb/&#34;&gt;noweb&lt;/a&gt;, filtering through &lt;a href=&#34;https://en.wikipedia.org/wiki/Sweave&#34;&gt;Sweave&lt;/a&gt; and into the Knitr we know and love today.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Anyway. You can work through your analysis in R exactly the same as usual, importing/creating data and analysing it however you see fit, then creating all your output tables/plots as chunks. For example, I can put the code above in a file called &lt;code&gt;my-code.R&lt;/code&gt; in the &lt;code&gt;analysis&lt;/code&gt; folder. You can split your analysis across multiple &lt;code&gt;.R&lt;/code&gt; files too, if that&amp;rsquo;s easier. Just make sure each chunk name, even if in different &lt;code&gt;.R&lt;/code&gt; files, is unique.&lt;/p&gt;
&lt;p&gt;Why do it this way? You&amp;rsquo;ll see in the next step.&lt;/p&gt;
&lt;h2 id=&#34;linking-the-two&#34;&gt;Linking the two&lt;/h2&gt;
&lt;p&gt;So, now we have our Scrivener setup to export to a plain text file for Bookdown to find in &lt;code&gt;book/src&lt;/code&gt;, and our analysis code in &lt;code&gt;analysis&lt;/code&gt;. But what if I now want to include the &lt;code&gt;example-table&lt;/code&gt; from above in my final document?&lt;/p&gt;
&lt;p&gt;This is where &lt;code&gt;knitr::read_chunk()&lt;/code&gt; comes in! This function reads in an external file, &lt;em&gt;without evaluating it&lt;/em&gt;. So, somewhere at the start of our &lt;code&gt;index.Rmd&lt;/code&gt; file for Bookdown, we just insert a chunk with the following:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;knitr::read_chunk(&amp;#34;analysis/my-code.R&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can do this for any &lt;code&gt;.R&lt;/code&gt; file you want included.&lt;/p&gt;
&lt;p&gt;Then, in Scrivener, at the point we want to insert the table, we just have to put an &lt;em&gt;empty&lt;/em&gt; Rmarkdown code chunk, making sure it has the &lt;em&gt;same&lt;/em&gt; chunk name as the table&amp;rsquo;s chunk in the &lt;code&gt;.R&lt;/code&gt; file. For example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Here is my text in Scrivener.

​```{r example-table}
```

See my table above for more.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will come out as plain text in our Scrivener export, and then when the book is rendered with Bookdown, be evaluated as code. Basically, if a chunk is empty, knitr looks for &lt;em&gt;another&lt;/em&gt; chunk with the same name, and runs the code within that. As we pulled in our &lt;code&gt;.R&lt;/code&gt; file with &lt;code&gt;read_chunk&lt;/code&gt;, Knitr instead goes and finds our &lt;code&gt;example-table&lt;/code&gt; chunk there, and runs it at the point in our document where we included our empty code chunk. 
&lt;span class=&#34;bg-yellow-200 dark:text-black px-2&#34;&gt;This is why every chunk needs a unique name!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We can even cross-reference these chunks the exact same way we usually &lt;a href=&#34;https://bookdown.org/yihui/bookdown/cross-references.html&#34;&gt;cross-reference things in Bookdown&lt;/a&gt;, with &lt;code&gt;\@ref(tab:example-table)&lt;/code&gt; for the above. It all just works exactly the same as regular Rmarkdown docs, we&amp;rsquo;re just inserting the chunk code from an external source.&lt;/p&gt;
&lt;p&gt;Phew! That&amp;rsquo;s a little mind-bendy, but it means that when we update any code in our &lt;code&gt;analysis&lt;/code&gt;, we can re-render the book with Bookdown and have the relevant code chunk automatically fetched and run within the text.&lt;/p&gt;
&lt;p&gt;The whole workflow therefore becomes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Setup Bookdown&lt;/li&gt;
&lt;li&gt;Analyse data with .&lt;code&gt;R&lt;/code&gt; files in &lt;code&gt;analysis&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;Create any tables/plots required as knitr chunks in &lt;code&gt;.R&lt;/code&gt; files in &lt;code&gt;analysis&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Write prose in Scrivener&lt;/li&gt;
&lt;li&gt;Include empty named chunks where tables/plots are required in Scrivener prose&lt;/li&gt;
&lt;li&gt;Compile from Scrivener to &lt;code&gt;.Rmd&lt;/code&gt; in Bookdown source directory&lt;/li&gt;
&lt;li&gt;Render final document with Bookdown&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All the normal Bookdown options for step 7 should work fine, including &lt;a href=&#34;https://jmablog.com/post/bookdown-not-bookout/&#34;&gt;my previous post&lt;/a&gt; about compiling to different document formats from Bookdown.&lt;/p&gt;
&lt;div class=&#34;aside&#34;&gt;
    &lt;p&gt;&lt;strong&gt;Update (22nd June 2021):&lt;/strong&gt; I recently stumbled over &lt;a href=&#34;https://yihui.org/en/2021/06/spin-child/&#34;&gt;this blog post&lt;/a&gt; by Yihui Xie, the main author of Knitr, about using &lt;code&gt;knitr::spin_child()&lt;/code&gt; to include R scripts in Rmarkdown documents. It pulls in and processes an entire R script file at a time rather than working by chunks, and can convert comments written in the R script into markdown. If you&amp;rsquo;d rather use individual script files to break up your work than chunks within files, this could be a nice alternative without needing to worry about chunk names.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;some-complications&#34;&gt;Some complications&lt;/h2&gt;
&lt;p&gt;There are a couple of caveats worth noting with this method. First, &lt;em&gt;only&lt;/em&gt; chunks from our &lt;code&gt;analysis&lt;/code&gt; files that we &lt;em&gt;explicitly&lt;/em&gt; include with an empty code chunk will be run. Anything not referenced with an empty code chunk somewhere in our final &lt;code&gt;.Rmd&lt;/code&gt; source text won&amp;rsquo;t be run. This means any setup code - for example, data creation/import/cleaning steps - in an &lt;code&gt;analysis&lt;/code&gt; script still need to be referenced somewhere, even if they aren&amp;rsquo;t creating a table or plot to be displayed. I find the easiest way to deal with this is to just put all the setup code in one big &lt;code&gt;data-setup&lt;/code&gt; chunk at the start of an &lt;code&gt;analysis&lt;/code&gt; script named something like &lt;code&gt;setup.R&lt;/code&gt;, then include an empty chunk with the same &lt;code&gt;data-setup&lt;/code&gt; name in &lt;code&gt;index.Rmd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Secondly, if you want to set code chunk options, you need to include those on the &lt;em&gt;empty chunks&lt;/em&gt;, rather than in the &lt;code&gt;analysis&lt;/code&gt; code chunks. This most usefully applies to plots in my experience so far. For example, to insert the &lt;code&gt;example-plot&lt;/code&gt; from above with some chunk options:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Here is a plot:

```{r example-plot, fig.cap=&amp;#34;Here is the caption for my example plot.&amp;#34;, fig.scap=&amp;#34;Example plot&amp;#34;}
```

Wow! What a plot. Figure \@ref(fig:example-plot) is amazing.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because this can get messy in Scrivener, I tend to just use individual chunk options to set plot captions as above, then set a whole load of default chunk options for plots in my setup in &lt;code&gt;index.Rmd&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;knitr::opts_chunk$set(echo = FALSE,
                      fig.pos = &amp;#34;tbp&amp;#34;,
                      out.extra = &amp;#34;&amp;#34;,
                      out.width = &amp;#34;100%&amp;#34;,
                      fig.retina = 2)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;post-processing&#34;&gt;Post processing&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;d like to make things a little more efficient, we can also link steps 6 and 7 from our workflow above using Scrivener&amp;rsquo;s ability to run a processing script on our exported plain text file. &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The below is for getting this working on MacOS. I don&amp;rsquo;t know how it differs for other operating systems. Soz.&lt;/p&gt;
&lt;p&gt;Head to &lt;code&gt;File &amp;gt; Compile&lt;/code&gt;, right-click your custom format and select &lt;code&gt;Edit Format&lt;/code&gt;, then click the &lt;code&gt;Processing&lt;/code&gt; menu option on the left. Tick the box that says &lt;code&gt;Post-process on command-line&lt;/code&gt; to enable the post-processing options below. Click the &lt;code&gt;Edit script&lt;/code&gt; button now to pop-up a little window that we can put our script in.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;08-processing.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;You can run R code from the command line using the Rscript executable and linking to it at the top of your shell script - if you&amp;rsquo;ve installed R, you can find where this is installed by running &lt;code&gt;which Rscript&lt;/code&gt; at the command-line. Mine was in &lt;code&gt;/usr/local/bin/Rscript&lt;/code&gt;, so I entered this at the top of my script following a &lt;a href=&#34;https://en.wikipedia.org/wiki/Shebang_(Unix)&#34;&gt;shebang&lt;/a&gt;. This lets us run regular R code in the rest of the script, that will be passed to Rscript to run.&lt;/p&gt;
&lt;p&gt;Scrivener also provides the full file path of the exported &lt;code&gt;.Rmd&lt;/code&gt; file to our script as a command-line argument. Using this, we can run &lt;code&gt;commandArgs(trailingOnly=TRUE)&lt;/code&gt; to collect those args. Then, using the &lt;a href=&#34;https://rprojroot.r-lib.org/index.html&#34;&gt;rprojroot package&lt;/a&gt;, we can run:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rprojroot::find_root(rprojroot::is_rstudio_project, path = args[1]) 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;hellip;to set our working directory to the Rstudio project directory for our Bookdown project (assuming you&amp;rsquo;re using Rstudio projects with your Bookdown setup) and then render our book! &lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Basically, just copy and paste this in to the &lt;code&gt;Edit Script&lt;/code&gt; pop-up:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/usr/local/bin/Rscript

args &amp;lt;- commandArgs(trailingOnly=TRUE)
proj &amp;lt;- rprojroot::find_root(rprojroot::is_rstudio_project, 
				path = args[1])
setwd(proj)
bookdown::render_book(&amp;#34;index.Rmd&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&#34;09-script.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Provided all your Bookdown files are setup (metadata in &lt;code&gt;index.Rmd&lt;/code&gt;, &lt;code&gt;_bookdown.yml&lt;/code&gt; and &lt;code&gt;_output.yml&lt;/code&gt; in project folder), the book should build.&lt;/p&gt;
&lt;p&gt;You can also just set the working directory manually if you don&amp;rsquo;t want to install rprojroot:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/usr/local/bin/Rscript

setwd(&amp;#34;~/path/to/project/folder&amp;#34;)
bookdown::render_book(&amp;#34;index.Rmd&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Just be aware this will be hard-coded into your compile format, so if you move your files, or change project, be sure to update it.&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;re able to set your project directory as the working directory, you can write any R code you want afterwards. For example, I use &lt;a href=&#34;https://rstudio.github.io/renv/index.html&#34;&gt;renv&lt;/a&gt; to manage my project libraries and have built my own custom book rendering function that I load with &lt;code&gt;devtools&lt;/code&gt;, so my full post-processing script in Scrivener is actually this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/usr/local/bin/Rscript

args &amp;lt;- commandArgs(trailingOnly=TRUE)
proj &amp;lt;- rprojroot::find_root(rprojroot::is_rstudio_project,
			path = args[1])
setwd(proj)

source(&amp;#34;renv/activate.R&amp;#34;)
devtools::load_all()
build_book()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I turn this post-processing on/off as I feel when I&amp;rsquo;m working - sometimes it&amp;rsquo;s easier to render the book from within Rstudio, if I&amp;rsquo;m tweaking Bookdown settings for example, and sometimes I want to iterate on my actual prose so I&amp;rsquo;ll set it to auto-render from Scrivener.&lt;/p&gt;
&lt;p&gt;Finally, because the shell Scrivener uses is (to quote the &lt;a href=&#34;https://www.literatureandlatte.com/learn-and-support/user-guides&#34;&gt;manual&lt;/a&gt;) &amp;ldquo;a very limited non-interactive shell&amp;rdquo;, I found it was having trouble finding my lualatex install. The answer was to enter this in the &lt;code&gt;Environment&lt;/code&gt; text field under the &lt;code&gt;Edit Script&lt;/code&gt; button:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/Users/james/bin:/Library/TeX/texbin
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This added my user bin folder and TeX install to the PATH environment variable for Scrivener&amp;rsquo;s shell. If you&amp;rsquo;re getting similar errors, you may need to figure out where the thing Scrivener is failing to find lives on your computer, and add that to the &lt;code&gt;Environment&lt;/code&gt; text field. Just enter the full paths to any folders you want found, separated by a colon.&lt;/p&gt;
&lt;h2 id=&#34;downsides&#34;&gt;Downsides&lt;/h2&gt;
&lt;p&gt;There are a couple downsides to this workflow that are worth noting. Mainly, it&amp;rsquo;s a one-way street from Scrivener to &lt;code&gt;.Rmd&lt;/code&gt;. If you render your final document, then notice some plot caption needs to be changed, you have to go all the way back to Scrivener and re-export to &lt;code&gt;.Rmd&lt;/code&gt; then re-render with Bookdown. The post-processing setup above can help minimise this, but it is a little more round-the-houses than just editing and knitting directly in Rstudio. I find this trade-off worth it, as it still saves me from all the time I used to spend exporting plots as images, importing them into Scrivener, then compiling from Scrivener anyway.&lt;/p&gt;
&lt;p&gt;Secondly, in my experience Scrivener doesn&amp;rsquo;t play all that nicely with version control systems like git. It will work, but because a &lt;code&gt;.scriv&lt;/code&gt; project file is really just a directory of other files, there&amp;rsquo;ll be a large amount of changes per commit every time you change something in your Scrivener project. So, if GitHub or similar is your preferred way of syncing your work across devices, it might be a little inconvenient. I find it best to set my &lt;code&gt;gitignore&lt;/code&gt; to exclude &lt;code&gt;.scriv&lt;/code&gt; files, only track my exported &lt;code&gt;.Rmd&lt;/code&gt; files in git, and then just sync Scrivener using &lt;a href=&#34;https://scrivener.tenderapp.com/help/kb/ios/dropbox-syncing-with-ios&#34;&gt;Dropbox&lt;/a&gt; to edit on the go with the iOS app. I also use the Snapshot feature in Scrivener itself as an in-built version control, if I ever need to rewind to previous drafts of pieces of text.&lt;/p&gt;
&lt;p&gt;I feel like these drawbacks are pretty manageable and are &lt;em&gt;definitely&lt;/em&gt; offset by all the writing tools Scrivener provides, now paired with all the functionality of Rmarkdown/Bookdown and LaTeX.&lt;/p&gt;
&lt;p&gt;Thanks for reading this behemoth of a post, and I hope it&amp;rsquo;s somewhat helpful to anyone looking to make use of these two amazing writing tools together. &lt;a href=&#34;https://twitter.com/jmablog&#34;&gt;Get in touch&lt;/a&gt; if you&amp;rsquo;ve got any other Scrivener/Bookdown tips!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;And bigger.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;You can also get here by right clicking any compile format and choosing &lt;code&gt;Edit Format&lt;/code&gt;.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;You could, of course, write your code in Scrivener directly - it&amp;rsquo;ll be run by R just fine when you export to .Rmd. But, it won&amp;rsquo;t be interactive - you won&amp;rsquo;t be able to run a bit of code, see how it comes out, tweak it, change it, re-run it&amp;hellip; If you&amp;rsquo;re like me, this is the main way I work on code. It&amp;rsquo;s sadly very rare for something to come out right the first time!&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;This is the main influence of Scrivomatic, which does the same to plug into Pandoc.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;code&gt;find_root()&lt;/code&gt; locates the Rstudio project directory for a file, even if that file is in multiple sub-directories. There are other ways to find working directories for R projects with rprojroot, so if you&amp;rsquo;re not using Rstudio projects, &lt;a href=&#34;https://rprojroot.r-lib.org/reference/criteria.html&#34;&gt;check out the docs&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        
        <item>
            <title>GNU Terry Pratchett with Netlify and Hugo</title>
            <link>https://jmablog.com/post/gnuterrypratchett/</link>
            <pubDate>Sun, 22 Nov 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/gnuterrypratchett/</guid>
            <description>&lt;p&gt;Terry Pratchett is my favourite author. It&amp;rsquo;s not even close. His wit and wisdom shaped about as much of my worldview as my own parents.&lt;/p&gt;
&lt;p&gt;He died in 2015, and it was awful. In the global trash fire of 2020, I&amp;rsquo;ve been re-reading a lot of his books for comfort, and it reminded me of this little endeavour.&lt;/p&gt;
&lt;p&gt;There is a project, &lt;a href=&#34;http://www.gnuterrypratchett.com&#34;&gt;GNU Terry Pratchett&lt;/a&gt;, to keep his name alive in the internet, based on an idea from one of his books. His name is placed into the headers of a website - little bits of metadata that sites transmit to tell your browser how to deal with their contents - and transmitted with every request to that site&amp;rsquo;s server. In this way, his name will ping-pong around the internet forever.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in taking part, I recommend checking out the &lt;a href=&#34;http://www.gnuterrypratchett.com&#34;&gt;project site&lt;/a&gt; for details on how you can include the header in a bunch of different types of sites. You can also install some &lt;a href=&#34;http://www.gnuterrypratchett.com/index.php#browsers&#34;&gt;browser extensions&lt;/a&gt; that allow you to detect the header on other people&amp;rsquo;s sites when they&amp;rsquo;ve included it. It&amp;rsquo;s delightful to see it light up in places you weren&amp;rsquo;t expecting it.&lt;/p&gt;
&lt;h2 id=&#34;netlify-and-hugo&#34;&gt;Netlify and Hugo&lt;/h2&gt;
&lt;p&gt;This site is built with &lt;a href=&#34;https://gohugo.io&#34;&gt;Hugo&lt;/a&gt; and hosted on &lt;a href=&#34;https://www.netlify.com/&#34;&gt;Netlify&lt;/a&gt;. Netlify has a couple fairly easy ways to customise your site headers - &lt;a href=&#34;https://docs.netlify.com/routing/headers/&#34;&gt;check out their docs here&lt;/a&gt;. The most direct way I found with Hugo is to drop a file just named &lt;code&gt;_headers&lt;/code&gt; in my &lt;code&gt;static&lt;/code&gt; folder (and I imagine there&amp;rsquo;ll be similarities with other static site generators). Yes, the underscore at the beginning is important, and no it&amp;rsquo;s not got a file extension. On build, Netlify moves this extensionless file up to the publish directory, and it becomes the headers file for your site.&lt;/p&gt;
&lt;p&gt;You can edit this extensionless file in any plain text editor. Within this &lt;code&gt;_headers&lt;/code&gt; file then, just enter the following:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/*
    X-Clacks-Overhead: GNU Terry Pratchett
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;/*&lt;/code&gt; means &amp;rsquo;everything within root&amp;rsquo;, so this will apply to every page on your site. Then, you can just declare the custom header. Don&amp;rsquo;t worry, it doesn&amp;rsquo;t actually &lt;em&gt;do&lt;/em&gt; anything except send the name. Browser&amp;rsquo;s will just ignore it. As proof - it&amp;rsquo;s activated on this site. Even if you don&amp;rsquo;t have the browser extensions installed, you can probably see it in your browser&amp;rsquo;s development tools, if you go looking under the Network tab.&lt;/p&gt;
&lt;p&gt;Anyway. Here&amp;rsquo;s a nice Terry quote to finish this post:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“It&amp;rsquo;s still magic even if you know how it&amp;rsquo;s done.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;GNU Terry Pratchett.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Bookdown, Not Bookout</title>
            <link>https://jmablog.com/post/bookdown-not-bookout/</link>
            <pubDate>Tue, 15 Sep 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/bookdown-not-bookout/</guid>
            <description>&lt;p&gt;I first got to grips with the &lt;a href=&#34;https://www.r-project.org/&#34;&gt;R coding language&lt;/a&gt; to do the statistical analysis for my &lt;a href=&#34;https://jmablog.com/research/pkvs/&#34;&gt;dissertation&lt;/a&gt;, but I still did all my actual writing in more traditional word processing apps. &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; This became a pain any time I needed to copy-paste an update into a table or, even worse, change a plot and re-export to an image and re-import it into my writing environment. Going forward, I resolved to find a better way to incorporate my analysis code and writing to avoid this problem.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://bookdown.org/&#34;&gt;Bookdown&lt;/a&gt; is a fantastic R package that compiles &lt;a href=&#34;https://rmarkdown.rstudio.com/&#34;&gt;Rmarkdown&lt;/a&gt; source documents into one big output, with code evaluated and, crucially, the ability to add cross-references to tables/plots etc. It seems to work best when producing HTML or PDF output, for which it has a whole bunch of great customisation options. This is great, as I always submit my final work in PDF. Unfortunately, due to needing to interact with lecturers and non-R-code-users for feedback on my work, I &lt;em&gt;also&lt;/em&gt; need it to work with the Word &lt;code&gt;docx&lt;/code&gt; file format. It can do this, but it does &lt;em&gt;not&lt;/em&gt; have nearly as many options for customising the output. And a lot of the things you can build when producing a PDF just flat out &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; work in Word.&lt;/p&gt;
&lt;p&gt;This has led to&amp;hellip; some work on my part.&lt;/p&gt;
&lt;h2 id=&#34;functionally-building-your-book&#34;&gt;Functionally building your book&lt;/h2&gt;
&lt;p&gt;The most obvious solution to me seemed to simply change what my code was doing depending on the format I was exporting to. I can tweak the final PDF output to be perfect, but the docx format has to be just good enough to get the point across to whoever I&amp;rsquo;m seeking feedback from.&lt;/p&gt;
&lt;p&gt;You can set Bookdown to export to multiple formats, and set options for each export format, using an &lt;code&gt;_output.yml&lt;/code&gt; file. But, weirdly, I didn&amp;rsquo;t actually find an easy way to change code execution within your document text itself based on the format currently being rendered by Bookdown. You&amp;rsquo;d think there&amp;rsquo;d be a way to declare &lt;code&gt;is(pdf)&lt;/code&gt; or &lt;code&gt;is(docx)&lt;/code&gt;  and execute appropriately, right? Unfortunately not. &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;According to &lt;a href=&#34;https://stackoverflow.com/questions/35144130/in-knitr-how-can-i-test-for-if-the-output-will-be-pdf-or-word&#34;&gt;this Stackoverflow thread&lt;/a&gt;, you can determine the currently rendering format with &lt;code&gt;rmarkdown::all_output_formats(knitr::current_input())[1]&lt;/code&gt;. I &lt;em&gt;think&lt;/em&gt; &lt;code&gt;_output.yml&lt;/code&gt; is supposed to be &amp;lsquo;shuffled&amp;rsquo; by Rstudio so that index 1 is always the &lt;em&gt;currently&lt;/em&gt; rendering output, but that wasn&amp;rsquo;t occurring when I tested it; every time I would just get back the &lt;em&gt;first&lt;/em&gt; format listed in &lt;code&gt;_output.yml&lt;/code&gt;, even if it wasn&amp;rsquo;t the one currently being rendered.So if &lt;code&gt;_output.yml&lt;/code&gt; had &lt;code&gt;bookdown::pdf_document&lt;/code&gt; and then &lt;code&gt;bookdown::word_document&lt;/code&gt; in it, all I would get back is &lt;code&gt;bookdown::pdf_document&lt;/code&gt; even when rendering to docx. &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;I could just swap in and out various outputs as I need them, of course, but I ended up taking a step back and considering what was really going on when rendering the document source files. If, like me, you&amp;rsquo;re using &lt;a href=&#34;https://rstudio.com/&#34;&gt;Rstudio&lt;/a&gt; as your IDE it gives you a handy &amp;lsquo;knit&amp;rsquo; or &amp;lsquo;build&amp;rsquo; button in your toolbar when it detects you&amp;rsquo;re in a Rmarkdown/Bookdown project. While nice, this abstraction actually ended up obscuring the underlying method until I went looking for it. Really all these buttons are doing is calling &lt;code&gt;bookdown::render_book&lt;/code&gt;, itself a wrap around &lt;code&gt;rmarkdown::render&lt;/code&gt;. This render function takes an argument for the format(s) to render when called, defaulting to the options found in &lt;code&gt;_output.yml&lt;/code&gt; for each particular output format.&lt;/p&gt;
&lt;p&gt;Once I realised that rendering a book is just another function, I decided to wrap it in my &lt;em&gt;own&lt;/em&gt; function. I can then provide formats as specific arguments to &lt;code&gt;bookdown::render_book&lt;/code&gt;, and use some yaml management packages (specifically &lt;a href=&#34;https://github.com/viking/r-yaml&#34;&gt;yaml&lt;/a&gt; and &lt;a href=&#34;https://ymlthis.r-lib.org/&#34;&gt;ymlthis&lt;/a&gt;) to read and write the different, &lt;em&gt;unique&lt;/em&gt; &lt;code&gt;_output.yml&lt;/code&gt; files for each call as I need them:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;build_book &amp;lt;- function(format = &amp;#34;all&amp;#34;){

  switch(format,
    &amp;#34;all&amp;#34; = formats &amp;lt;- c(&amp;#34;bookdown::pdf_document2&amp;#34;,
                         &amp;#34;bookdown::word_document2&amp;#34;),
    &amp;#34;pdf&amp;#34; = formats &amp;lt;- &amp;#34;bookdown::pdf_document2&amp;#34;,
    &amp;#34;word&amp;#34; = formats &amp;lt;- &amp;#34;bookdown::word_document2&amp;#34;
  )

  for(fmt in formats) {
  
    if(grepl(&amp;#34;all&amp;#34;, fmt)) {
      out_yml &amp;lt;- yaml::read_yaml(&amp;#34;_all_output.yml&amp;#34;)
      ymlthis::use_yml_file(ymlthis::as_yml(out_yml), &amp;#34;_output.yml&amp;#34;)
    }

    if(grepl(&amp;#34;pdf&amp;#34;, fmt)) {
      out_yml &amp;lt;- yaml::read_yaml(&amp;#34;_pdf_output.yml&amp;#34;)
      ymlthis::use_yml_file(ymlthis::as_yml(out_yml), &amp;#34;_output.yml&amp;#34;)
    }
    
    if(grepl(&amp;#34;word&amp;#34;, fmt)) {
      out_yml &amp;lt;- yaml::read_yaml(&amp;#34;_word_output.yml&amp;#34;)
      ymlthis::use_yml_file(ymlthis::as_yml(out_yml), &amp;#34;_output.yml&amp;#34;)
    }

    bookdown::render_book(here::here(&amp;#34;index.Rmd&amp;#34;),
                          output_format = fmt)

    fs::file_delete(&amp;#34;_output.yml&amp;#34;)
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This pulls in a specific yaml file for a format from the project folder and sets it as the &lt;code&gt;_output.yml&lt;/code&gt; for Bookdown to find and use. Now, when rendering, using &lt;code&gt;rmarkdown::all_output_formats(knitr::current_input())[1]&lt;/code&gt; returns the &lt;em&gt;correct&lt;/em&gt; file format for the current render, as it&amp;rsquo;s the &lt;em&gt;only&lt;/em&gt; format in the output yaml file! This allowed me to put this at the start of my bookdown source files:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;fmt &amp;lt;- rmarkdown::all_output_formats(knitr::current_input())[1]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And then test for output with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;if(!grepl(&amp;#34;word&amp;#34;, fmt)) {
  my_table %&amp;gt;%
    kableExtra::kbl(caption = &amp;#34;My full table caption&amp;#34;,
                 caption.short = &amp;#34;Short caption for ToC&amp;#34;,
                 booktabs = TRUE) %&amp;gt;%
    kableExtra::kable_styling(latex_options = c(&amp;#34;striped&amp;#34;,
                                                &amp;#34;HOLD_position&amp;#34;,
                                                &amp;#34;scale_down&amp;#34;))
} else {
  exTab %&amp;gt;%
    knitr::kable(caption = &amp;#34;My full table caption&amp;#34;,
                 booktabs = TRUE)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This lets me, for example here, use &lt;a href=&#34;https://haozhu233.github.io/kableExtra/&#34;&gt;kableExtra&lt;/a&gt; to style my table for PDF/HTML output, then just use regular ol&amp;rsquo; &lt;code&gt;knitr::kable&lt;/code&gt; to render it for docx.&lt;/p&gt;
&lt;h2 id=&#34;taking-it-further&#34;&gt;Taking it further&lt;/h2&gt;
&lt;p&gt;Once I started writing my own book rendering/wrapper function, other opportunities opened up for customising my build process. For example - one thing I like to do is build my drafts and save them into folders with today&amp;rsquo;s date, so I can put my feedback from lecturers in that same folder and keep it all together for easy reference. So I added the following to my &lt;code&gt;build_book()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;build_path &amp;lt;- glue::glue(&amp;#34;book/builds/{Sys.Date()}&amp;#34;)

bookdown_yml &amp;lt;-
      ymlthis::yml_bookdown_opts(.yml = ymlthis::yml_empty(),
        book_filename = &amp;#34;My Project&amp;#34;,
        rmd_subdir = c(&amp;#34;src&amp;#34;),
        delete_merged_file = FALSE,
        output_dir = build_path
      )
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now by creating a custom &lt;code&gt;_bookdown.yml&lt;/code&gt; file for each call to &lt;code&gt;build_book()&lt;/code&gt;, each build will save into a &lt;code&gt;book/src/DATE&lt;/code&gt; specific folder.&lt;/p&gt;
&lt;p&gt;There are &lt;em&gt;tons&lt;/em&gt; of ways to further change how Bookdown builds your book based on arguments you provide to your own &lt;code&gt;build_book&lt;/code&gt;, swapping in and out various Bookdown configuration files as required. Is this the most efficient way to customise your Bookdown project? Probably not, with all the creating and changing of existing yaml files, but speed isn&amp;rsquo;t really my concern here - running &lt;code&gt;build_book&lt;/code&gt; and having to step back and wait for a minute or two for my code to run is much more preferable to the &lt;em&gt;stupid&lt;/em&gt; amounts of time I spent correcting fiddly tables/plot/cross reference output by hand in Word before!&lt;/p&gt;
&lt;h2 id=&#34;word--docx-output-tweaks&#34;&gt;Word / .docx output tweaks&lt;/h2&gt;
&lt;p&gt;So now I can customise my output based on where I&amp;rsquo;m rendering, I need to fix a couple of other things in my docx output. These now need to be done by editing my reference document for Bookdown docx output. For a primer on creating and editing your reference doc, &lt;a href=&#34;https://rmarkdown.rstudio.com/articles_docx.html&#34;&gt;check out this article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One extra thing I needed was &lt;em&gt;numbered&lt;/em&gt; section headings, not just H1, H2 etc rendered as headings. This can&amp;rsquo;t just be set in Bookdown, but instead can be done in your reference doc by selecting your header, going to &lt;code&gt;Format -&amp;gt; Style... -&amp;gt; Modify&lt;/code&gt;, and then finding this hidden gem of a menu in the lower left of the style formatting menu:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;num-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then clicking &lt;code&gt;Outline Numbered&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;num-2.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;You can also click &amp;lsquo;customise&amp;rsquo; here for some extra options, such as how much sub-headings should indent. Be aware you also need to do this for &lt;em&gt;every&lt;/em&gt; heading you want numbered, so H1, H2, etc. I then combined this with &lt;code&gt;build_book&lt;/code&gt; to choose whether to number headings in docx output:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;build_book &amp;lt;- function(format = &amp;#34;word&amp;#34;, word_num = TRUE){
    
  ...
   
    if(grepl(&amp;#34;word&amp;#34;, fmt)) {
      if(word_num = TRUE) {
        out_yml &amp;lt;- yaml::read_yaml(&amp;#34;_word_output_numbered.yml&amp;#34;)
        ymlthis::use_yml_file(ymlthis::as_yml(out_yml), &amp;#34;_output.yml&amp;#34;)
        } else {
        out_yml &amp;lt;- yaml::read_yaml(&amp;#34;_word_output.yml&amp;#34;)
        ymlthis::use_yml_file(ymlthis::as_yml(out_yml), &amp;#34;_output.yml&amp;#34;)
        }
    }

  ...

}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And just refer to the two differently formatted ref docx&amp;rsquo;s within &lt;code&gt;_word_output_numbered.yml&lt;/code&gt; and &lt;code&gt;_word_output.yml&lt;/code&gt; respectively. Each one gets swapped in when called upon.&lt;/p&gt;
&lt;p&gt;Finally, I needed to put in a table of contents and lists of figures/tables at the start of the document. There really doesn&amp;rsquo;t seem to be an easy way to create ToCs in docx from Bookdown, but fortunately it&amp;rsquo;s just a quick click or two in Word to auto-generate them from document headings or existing document styles. &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; But, I wanted some blank pages at the start, with &amp;lsquo;Table of Contents&amp;rsquo; etc as a heading on each one, so at least I had &lt;em&gt;space&lt;/em&gt; for all these things set aside automatically that I didn&amp;rsquo;t need to think about.&lt;/p&gt;
&lt;p&gt;You &lt;em&gt;can&lt;/em&gt; include some basic latex functions in Rmarkdown, one of which is &lt;code&gt;\newpage&lt;/code&gt; to start a new page. But, if I tried adding &lt;code&gt;# Table of Contents&lt;/code&gt; as a header on a page at the start of the document, when I auto generate the ToC in Word this heading &lt;em&gt;itself&lt;/em&gt; gets included in the ToC.&lt;/p&gt;
&lt;p&gt;I ended up declaring &lt;a href=&#34;https://pandoc.org/MANUAL.html#output&#34;&gt;pandoc custom style fences&lt;/a&gt; to give this page the style of &amp;lsquo;Title&amp;rsquo; rather than &amp;lsquo;heading&amp;rsquo;, so it won&amp;rsquo;t be included in the auto generated ToC. I also used &lt;a href=&#34;https://glue.tidyverse.org/&#34;&gt;glue&lt;/a&gt; and the output detector from above to only include it in docx output:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;if(grepl(&amp;#34;word&amp;#34;, fmt)) {
  word_toc &amp;lt;- glue::glue(&amp;#39;
\\newpage
::: {{custom-style=&amp;#34;Title&amp;#34;}}
Table of Contents
:::
\\newpage
::: {{custom-style=&amp;#34;Title&amp;#34;}}
List of Figures
:::
\\newpage
::: {{custom-style=&amp;#34;Title&amp;#34;}}
List of Tables
:::
\\newpage
::: {{custom-style=&amp;#34;Title&amp;#34;}}
List of Appendices
:::
             &amp;#39;)
} else {
  word_toc &amp;lt;- NULL
}

word_toc
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Remember to escape your forward slashes and your curly brackets in glue by doubling up!&lt;/p&gt;
&lt;h2 id=&#34;writing-environment&#34;&gt;Writing environment&lt;/h2&gt;
&lt;p&gt;Just as an aside, as great as Rstudio is, I wouldn&amp;rsquo;t really recommend it as the best pure writing environment. You can certainly make it a bit nicer with themes and by editing the font used, but you&amp;rsquo;re not going to get away from its original purpose as a coding environment. While fine for coding within projects, there was also going to be quite a lot of just regular prose writing, and I wanted to find somewhere a bit nicer to work on those parts.&lt;/p&gt;
&lt;p&gt;Although Rmarkdown&amp;rsquo;s .Rmd files are theoretically plain text files, I found options to be limited when looking for a writing app that can handle them. Initially I tried using &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;VS Code&lt;/a&gt;, as while first and foremost a coding environment, it&amp;rsquo;s highly customisable. In particular, a &lt;a href=&#34;https://ethanschoonover.com/solarized/&#34;&gt;solarized&lt;/a&gt; colour theme, an R markdown plugin, and discovering VS Code&amp;rsquo;s &lt;a href=&#34;https://code.visualstudio.com/docs/getstarted/tips-and-tricks#_zen-mode&#34;&gt;zen mode&lt;/a&gt; got me quite a long way towards a pleasant writing environment, but it still felt a little janky.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve ended up settling on &lt;a href=&#34;https://ia.net/writer&#34;&gt;IA Writer&lt;/a&gt; as my main &amp;lsquo;writing&amp;rsquo; app of choice. It handles .Rmd files without a problem, feels super smooth, and full-screen provides a nice, distraction free writing environment. It&amp;rsquo;s not particularly cheap, but you get what you pay for. As a bonus, I can use &lt;a href=&#34;https://workingcopyapp.com/&#34;&gt;Working Copy&lt;/a&gt; to sync my git repo for each project to my mobile devices and continue working on them in IA Writer&amp;rsquo;s mobile apps just as if I was on desktop.&lt;/p&gt;
&lt;p&gt;If IA Writer is a bit too steep in cost, &lt;a href=&#34;https://typora.io/&#34;&gt;Typora&lt;/a&gt; is a really nice alternative. It&amp;rsquo;s currently free while in beta, so not sure how much longer that&amp;rsquo;s going to be the case, but it also handles .Rmd files really well. I just preferred some of the library/file management options in IA myself.&lt;/p&gt;
&lt;p&gt;On mobile, &lt;a href=&#34;https://1writerapp.com/&#34;&gt;1Writer&lt;/a&gt; or &lt;a href=&#34;https://www.textasticapp.com/&#34;&gt;Textastic&lt;/a&gt; are also great choices for iOS, and &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.jotterpad.x&amp;amp;hl=en_US&#34;&gt;JotterPad&lt;/a&gt; on Android is also great for markdown, although I haven&amp;rsquo;t been able to check it works with .Rmd files myself yet.&lt;/p&gt;
&lt;h2 id=&#34;reproducibility&#34;&gt;Reproducibility&lt;/h2&gt;
&lt;p&gt;Once I start cobbling together workflows and hacks like those I&amp;rsquo;ve detailed in this blog post, I invariably start worrying about stability and reproducibility. &lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; What happens when I want to start a new project? Or if I lose or break my laptop and I need to start over again on a new device?&lt;/p&gt;
&lt;p&gt;This is where working in code is really handy, and having recently tried my hand at &lt;a href=&#34;https://jmablog.com/post/tinier-release/&#34;&gt;R package development&lt;/a&gt; comes in &lt;em&gt;really&lt;/em&gt; handy. See, now I know just enough about how R works with packages to put my custom project functions - like &lt;code&gt;build_book()&lt;/code&gt; - in an R/ folder within my project, and have the &lt;a href=&#34;https://usethis.r-lib.org/&#34;&gt;usethis&lt;/a&gt; package create me a DESCRIPTION file that lists my project&amp;rsquo;s dependencies.&lt;/p&gt;
&lt;p&gt;I can then also drop all my book building assets - like my custom reference docs for docx files, custom &lt;a href=&#34;https://bookdown.org/yihui/rmarkdown-cookbook/latex-preamble.html&#34;&gt;latex preambles&lt;/a&gt; &lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;, bibliography files, the works - into that same project, push it to GitHub, and turn that whole thing into a &lt;a href=&#34;https://github.blog/2019-06-06-generate-new-repositories-with-repository-templates/&#34;&gt;template repository&lt;/a&gt;. &lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; Now, anytime I need to create a new Bookdown project, I can just clone that repo, and run &lt;code&gt;devtools::load_all()&lt;/code&gt; to have my custom &lt;code&gt;build_book&lt;/code&gt; function back in action!&lt;/p&gt;
&lt;p&gt;Taking it a step further, I can use the new-ish &lt;a href=&#34;https://rstudio.github.io/renv/&#34;&gt;renv&lt;/a&gt; package to create a &lt;code&gt;renv.lock&lt;/code&gt; file in my template repo that I can then use to &lt;em&gt;exactly&lt;/em&gt; re-install the package dependencies I might need for any book project. &lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;As a side bonus, while reassuring myself in creating a stable and reproducible project setup, this also follows a lot of the steps recommended to turn your research into a &lt;a href=&#34;https://peerj.com/preprints/3192v2/&#34;&gt;research compendium&lt;/a&gt;. This means that someone &lt;em&gt;else&lt;/em&gt; can also download the git repositories I create this way, and similarly, use my renv.lock or package dependencies in DESCRIPTION to very quickly get up and running with a similar environment to mine to test out my work for themselves. I could even take it a step further and include a Dockerfile and link to an online Rstudio server using the &lt;a href=&#34;https://github.com/karthik/holepunch&#34;&gt;holepunch package&lt;/a&gt; to recreate it exactly.&lt;/p&gt;
&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;This blog post is really the result of a couple weekends of StackOverflow diving and thinking about what I really need for my next big writing project. It can be a bit overwhelming working with something that has as many options as Bookdown/Rmarkdown does. The sheer amount of configurations alongside the integration with Rstudio can lead you to forget that, underneath it all, it&amp;rsquo;s all still just code you can pull apart and make do what you want with a little sideways thinking. I found a lot of questions online while researching this stuff from people trying to make Bookdown do something from within, when really a little meta-coding with a function that just swaps out different &lt;code&gt;_bookdown.yml&lt;/code&gt; files as needed would do the trick.&lt;/p&gt;
&lt;p&gt;I hope this post helps a little bit for those out there in the same boat as me. Us poor souls that still have to deal with docx and Bookdown need to stick together. If you have your own Bookdown/Rmarkdown hints and tips, &lt;a href=&#34;https://twitter.com/jmablog&#34;&gt;tweet them to me&lt;/a&gt;, I&amp;rsquo;d love to hear them!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I like &lt;a href=&#34;https://www.literatureandlatte.com/scrivener/overview&#34;&gt;Scrivener&lt;/a&gt;, but man, be ready to spend some time reading the manual and figuring out all the little things you can tweak.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;There is &lt;code&gt;knit::is_latex_output()&lt;/code&gt; and &lt;code&gt;knit::is_html_output()&lt;/code&gt; but no &lt;code&gt;is_word&lt;/code&gt;. You could work in the negative, but I wanted a way to be explicitly clear about exactly the format being rendered.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Maybe I was doing something wrong, but it never worked for me.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;And nicely, table and figure captions from kable/knitr get given their own styles that can be used to generate separate indexes in Word. See &lt;a href=&#34;https://support.microsoft.com/en-gb/office/create-or-change-a-table-of-figures-3bfbf7e6-2346-42fb-9810-09c113e1cb60&#34;&gt;this help article&lt;/a&gt; for more on generating lists of figures/tables in Word from document styles.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;My dissertation project was such a house of cards by the end that I was scared to change anything in any configuration menu/file incase I broke the whole thing.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;Now that&amp;rsquo;s a whole other rabbit hole to fall down&amp;hellip;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;For a fun trick, setup this template repo with exactly the folder structure you want in all your projects, and use &lt;code&gt;.keep&lt;/code&gt; hidden files to keep otherwise empty directories synced in git. Useful for that &amp;lsquo;data&amp;rsquo; folder you want to keep in the template but don&amp;rsquo;t actually have any data in yet.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;renv is great, and near as I can tell is aiming to replicate the functionality of things like npm&amp;rsquo;s package.json file and python&amp;rsquo;s virtual environments. Highly recommend checking out, it&amp;rsquo;s worked very smoothly for me so far.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        
        <item>
            <title>How joyful were the Friends main characters?</title>
            <link>https://jmablog.com/post/tt-friends/</link>
            <pubDate>Wed, 09 Sep 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/tt-friends/</guid>
            <description>&lt;p&gt;&lt;em&gt;(&lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;Tidy Tuesday&lt;/a&gt; is a project to supply weekly data sets for R users to practice their coding skills on. You can find &lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;full details here&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/rfordatascience/tidytuesday/blob/master/data/2020/2020-09-08/readme.md&#34;&gt;This week&amp;rsquo;s&lt;/a&gt; Tidy Tuesday dataset makes use of the &lt;code&gt;friends&lt;/code&gt; &lt;a href=&#34;https://github.com/EmilHvitfeldt/friends&#34;&gt;package&lt;/a&gt; put together by &lt;a href=&#34;https://twitter.com/Emil_Hvitfeldt&#34;&gt;Emil Hvitfeldt&lt;/a&gt;. It contains a bunch of datasets put together by analysing the transcripts of the TV show &amp;lsquo;Friends&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;One of these datasets includes &amp;rsquo;emotions&amp;rsquo;, categorised into one of seven groups that included the emotions &amp;lsquo;joyful&amp;rsquo; and &amp;lsquo;sad&amp;rsquo;. These describe the emotion being expressed at any particular line in an episode&amp;rsquo;s script (referred to as &amp;lsquo;utterances&amp;rsquo; in the data). I thought it would be fun to see what the overall &amp;rsquo;emotion score&amp;rsquo; of each episode for each character would be, where a &amp;lsquo;joyful&amp;rsquo; utterance scores +1 and a &amp;lsquo;sad&amp;rsquo; utterance scores -1. Would the overall emotion score for each episode come out positive or negative?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;friends-plot.png&#34;&gt;&lt;img src=&#34;friends-plot.png&#34; alt=&#34;&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Overall, Friends is a more joyful show than not! &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Mind, the &amp;rsquo;emotions&amp;rsquo; dataset only seems to cover seasons 1-4, so that&amp;rsquo;s what ended up on the plot. &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; Generally characters finish seasons on an up, except for poor Phoebe with season 2. However Phoebe does also get the highest joyful score with season 4 episode 17, which is the one where she finds out she&amp;rsquo;s pregnant with triplets, so swings and roundabouts!&lt;/p&gt;
&lt;p&gt;Chandler has the least number of negative scores across all 4 seasons with just 5 scores &amp;lt; 0, while Ross has the saddest time of it with 16 scores &amp;lt; 0. However Ross is also the only character other than Phoebe to score above 10 in any episode, twice, so I guess the lowest lows lead to the highest highs?&lt;/p&gt;
&lt;p&gt;This plot uses a combination of &lt;a href=&#34;https://github.com/cttobin/ggthemr&#34;&gt;ggthemr&amp;rsquo;s&lt;/a&gt; &amp;lsquo;pale&amp;rsquo; theme &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; further customised to remove some axis lines/ticks and change the background colour. I also used &lt;a href=&#34;https://github.com/wilkelab/ggtext&#34;&gt;ggtext&lt;/a&gt; to add in the TV show logo to the title with &lt;code&gt;element_markdown&lt;/code&gt; and &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;, along with &lt;code&gt;glue&lt;/code&gt; to create a column of &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags containing everyone&amp;rsquo;s headshots that could be used as a facet label. Before this, I was using just text for facet labels, and I stumbled onto using &lt;code&gt;strip.text.y = element_text(angle = 0, hjust = 0)&lt;/code&gt; to turn the facet labels for characters to horizontal and left-aligned, which looks much nicer for this kind of thing so I left it in as a note to future James.&lt;/p&gt;
&lt;p&gt;Oh! And I even used my very own &lt;a href=&#34;https://github.com/jmablog/tinieR&#34;&gt;tinieR&lt;/a&gt; package at the end to reduce the plot file size for uploading to the web. Pretty cool!&lt;/p&gt;
&lt;p&gt;Code (also at &lt;a href=&#34;https://github.com/jmablog/jmablog-code-snippets/blob/master/tidy-tuesday/friends.Rmd&#34;&gt;GitHub&lt;/a&gt;):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;library(tidyverse)
library(ggthemr)
library(ggtext)
library(tinieR)

ggthemr(&amp;#34;pale&amp;#34;)

tuesdata &amp;lt;- tidytuesdayR::tt_load(&amp;#39;2020-09-08&amp;#39;)

main_cast &amp;lt;- c(&amp;#34;Monica Geller&amp;#34;, &amp;#34;Rachel Green&amp;#34;, &amp;#34;Phoebe Buffay&amp;#34;, &amp;#34;Chandler Bing&amp;#34;, &amp;#34;Joey Tribbiani&amp;#34;, &amp;#34;Ross Geller&amp;#34;)

data &amp;lt;- 
  tuesdata$friends %&amp;gt;%
  left_join(tuesdata$friends_emotions, by = c(&amp;#34;season&amp;#34;, &amp;#34;episode&amp;#34;, &amp;#34;scene&amp;#34;, &amp;#34;utterance&amp;#34;)) %&amp;gt;%
  filter(emotion == &amp;#34;Joyful&amp;#34; | emotion == &amp;#34;Sad&amp;#34;) %&amp;gt;%
  filter(speaker %in% main_cast)

emotion_scores &amp;lt;- data %&amp;gt;%
  select(-text) %&amp;gt;%
  mutate(emotion_score = case_when(emotion == &amp;#34;Joyful&amp;#34; ~ 1,
                                   emotion == &amp;#34;Sad&amp;#34; ~ -1)) %&amp;gt;%
  group_by(speaker, season, episode) %&amp;gt;%
  summarise(episode_score = sum(emotion_score)) %&amp;gt;%
  ungroup()

emotion_scores %&amp;gt;%
  mutate(speaker = str_extract(speaker, &amp;#34;^[a-zA-Z]+&amp;#34;),
         season = glue::glue(&amp;#34;Season {season}&amp;#34;),
         headshot = glue::glue(&amp;#34;&amp;lt;img src=&amp;#39;{speaker}.png&amp;#39; width = &amp;#39;35&amp;#39; /&amp;gt;&amp;#34;)) %&amp;gt;%
  ggplot(aes(episode, episode_score, color = speaker)) +
  geom_point(alpha = .5, show.legend = F) +
  geom_smooth(se = F, show.legend = F) +
  geom_hline(yintercept = 0, color = &amp;#34;grey&amp;#34;) +
  scale_y_continuous(breaks = c(-5, 10)) +
  labs(x = &amp;#34;Episode&amp;#34;, y = &amp;#34;Emotion Score&amp;#34;,
       title = &amp;#34;How joyful were the &amp;lt;img src = &amp;#39;friends-logo-tr.png&amp;#39; width = &amp;#39;90&amp;#39; /&amp;gt; main characters?&amp;#34;,
       subtitle = &amp;#34;&amp;#39;Joyful&amp;#39; utterance = Score +1, &amp;#39;Sad&amp;#39; utterance = Score -1, summed per episode&amp;#34;) +
  facet_grid(headshot~season) +
  theme(#strip.text.y = element_text(angle = 0, hjust = 0),
        strip.text.y = element_markdown(angle = 0, hjust = 0),
        panel.grid = element_blank(),
        axis.line.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.text.x = element_blank(),
        axis.title = element_text(face = &amp;#34;bold&amp;#34;),
        strip.text.x = element_text(face = &amp;#34;bold&amp;#34;),
        plot.title = element_markdown(size = 16),
        plot.subtitle = element_text(size = 8),
        plot.margin = margin(1, 1, 1, 1, &amp;#34;cm&amp;#34;),
        plot.background = element_rect(fill = &amp;#34;#fffcf2&amp;#34;),
        panel.background = element_rect(fill = &amp;#34;#fffcf2&amp;#34;),
        strip.background = element_rect(fill = &amp;#34;#fffcf2&amp;#34;))

ggsave(&amp;#34;friends-plot.png&amp;#34;)
tinify(&amp;#34;friends-plot.png&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Shocker.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Maybe it gets darker in the later seasons.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&amp;lsquo;Rachel Green&amp;rsquo; coming out green on the plot was entirely a coincidence, but one I&amp;rsquo;m happy to take credit for nontheless.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        
        <item>
            <title>Hugo Clinic Notes Theme</title>
            <link>https://jmablog.com/post/hugo-clinic-notes/</link>
            <pubDate>Sat, 05 Sep 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/hugo-clinic-notes/</guid>
            <description>&lt;p&gt;While &lt;a href=&#34;https://jmablog.com/pkvs&#34;&gt;publishing my dissertation online&lt;/a&gt; and putting together the &lt;a href=&#34;https://pkc.netlify.app/&#34;&gt;Parkour Clinic&lt;/a&gt; site over the summer, I got increasingly familiar with the &lt;a href=&#34;https://gohugo.io&#34;&gt;Hugo&lt;/a&gt; static site generator. I&amp;rsquo;d first set myself up with Hugo when I decided to scrap my previous personal training site, and move the few blog posts I had there over to a personal blog instead. &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; At the time I just picked a Hugo theme, dropped it in, exported my blog posts from Squarespace into markdown, and left it ticking away as it was.&lt;/p&gt;
&lt;p&gt;Eventually, though, I started tinkering with the theme I was using, extending the templates provided to customise how my blog was running. Likewise, when it came time to create Parkour Clinic, I knew I wanted to be able to use template partials to handle things like a navigation bar, that could be updated in one place but included on all the pages across the site. The last time I had properly built a site for myself from scratch had been almost twenty years ago; I remembered well the pain of changing one navigation menu URL and having to go change it by hand across dozens of html files. No thanks.&lt;/p&gt;
&lt;p&gt;My ongoing experience of getting more comfortable with Hugo&amp;rsquo;s templating sparked an idea for another problem I was trying to solve at the same time - how did I want to create and store my patient clinical notes for Parkour Clinic?&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d been thinking about this for a while. All my sports therapy work placements to date had essentially used hard copies of forms filled out by hand and kept in a filing cabinet - I didn&amp;rsquo;t have the space (or printer toner) for that. Neither did I want to use Word or similar to actually create the notes - I&amp;rsquo;ve gotten used to the speed and simplicity of writing in markdown. Besides, there wasn&amp;rsquo;t really anything beyond the occasional table or image that I need to include in a patient&amp;rsquo;s notes that needed fancier layout abilities than markdown provides.&lt;/p&gt;
&lt;p&gt;But, I didn&amp;rsquo;t really want to just have a directory of .md files on my hard drive - it&amp;rsquo;d be nice to have some interconnectivity between these notes, so I could flip between them quickly or sort and group them in various ways (by date or by patient name, for example). And I wanted the markdown processed when viewing, so it&amp;rsquo;s easier to read, and be able to print the formatted document to PDF or similar if I needed to share it with a patient.&lt;/p&gt;
&lt;p&gt;Solutions for clinics are out there - &lt;a href=&#34;https://www.cliniko.com/&#34;&gt;Cliniko&lt;/a&gt; seemed to be a popular one I saw a lot while researching - but I didn&amp;rsquo;t want to pay for a service like this, as I&amp;rsquo;m aiming to keep the costs of Parkour Clinic as low as possible since I&amp;rsquo;m not really monetising it. I could use a markdown based notes app, like &lt;a href=&#34;https://bear.app/&#34;&gt;Bear&lt;/a&gt;, but this would tie me in to their ecosystem (even if just a bit, as it&amp;rsquo;s fairly easy to export from something like Bear), and I was a bit iffy about sending off all my patient info to some cloud server somewhere.&lt;/p&gt;
&lt;p&gt;So I built my own!&lt;/p&gt;
&lt;h2 id=&#34;hugo-clinic-notes-theme&#34;&gt;Hugo clinic notes theme&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://themes.gohugo.io/hugo-clinic-notes/&#34;&gt;Hugo Clinic Notes&lt;/a&gt; is a theme for Hugo that lets you create markdown based patient notes, and then view them on a site running on Hugo&amp;rsquo;s bundled local web server. It&amp;rsquo;s been on my GitHub for a little while but just got accepted onto the Hugo themes repository, where you can &lt;a href=&#34;https://themes.gohugo.io/theme/hugo-clinic-notes/&#34;&gt;try a demo&lt;/a&gt; and find instructions for downloading it. &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Admittedly this is probably for quite a niche audience of those who 1) run some kind of clinic/service that keeps records like this and 2) is nerdy enough to want to work in markdown and on a local web server, but if that&amp;rsquo;s you and you&amp;rsquo;re looking for a relatively easy and free way to run a patient records system this might do the job. You can customise the forms included or just delete them outright and use your own designs, and there&amp;rsquo;s a number of views and ways to get to the document you want.&lt;/p&gt;
&lt;p&gt;There are some nice little additions I&amp;rsquo;m quite proud of, like the use of &lt;code&gt;@media print&lt;/code&gt; CSS media queries to remove the top and bottom navigations when printing any document (useful for creating PDFs of your completed forms to send to patients), or the way you can include table of contents based on markdown headings in the top navigation by just changing a setting in the yaml front matter. Oh, and the way the loop logic on the list-all-patients-by-name index page only create alphabet headers for letters that actually have patients under them. Man, that one took a while&amp;hellip; &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a couple hints: it&amp;rsquo;s just in a browser, so use the good ol&amp;rsquo; &lt;code&gt;Cmd / Ctrl + F&lt;/code&gt; find command to search text for the bits you need. It&amp;rsquo;s all just markdown under the hood so I also suggest using Git or another version control system to kind of &amp;rsquo;lock-in&amp;rsquo; each form as you complete it or make edits to one, to create a really nice paper trail of patient records over time. &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; If you want to get really advanced, I&amp;rsquo;ve even set up macros with &lt;a href=&#34;https://www.keyboardmaestro.com/main/&#34;&gt;Keyboard Maestro&lt;/a&gt; to gather input from prompts and then use Hugo commands at the terminal to create new forms with the correct patient name/date/time for an appointment and open them for editing in my markdown editor&amp;hellip; But that&amp;rsquo;s up to you.&lt;/p&gt;
&lt;p&gt;Like I said, this one is probably solely for me. But, building it was hugely rewarding, and I&amp;rsquo;ve been using it for a couple months now with my Parkour Clinic appointments where it&amp;rsquo;s solved my problem of patient notes storage practically perfectly. If nothing else, it shows how useful a tool like Hugo can be for putting a graphical frontend on a very simple backend.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Why pick Hugo, over the growing number of other static site generators available these days? To be honest, it was just because my wife used Hugo for &lt;a href=&#34;https://localghost.dev/&#34;&gt;her own blog&lt;/a&gt; and it was useful to be able to lean over to her on the sofa and point at bits of code while going &amp;ldquo;WHY ISN&amp;rsquo;T THIS WORKING&amp;rdquo;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I didn&amp;rsquo;t quite appreciate the time frame between submitting the theme to the Hugo repo and it getting accepted, so after a few weeks of radio silence I kind of thought it was a nice way of saying &amp;ldquo;your theme isn&amp;rsquo;t accepted and we&amp;rsquo;re just going to leave it until we all quietly forget about it&amp;rdquo;, so it was a nice surprise to get the email notification saying it was approved.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;And required learning about &lt;a href=&#34;https://gohugo.io/functions/scratch#readout&#34;&gt;scratch&lt;/a&gt;!&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Just keep it local - I wouldn&amp;rsquo;t recommend syncing to a service like GitHub, even a private repo, for confidentiality reasons.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        
        <item>
            <title>tinieR 0.3.0</title>
            <link>https://jmablog.com/post/tinier-update/</link>
            <pubDate>Sun, 30 Aug 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/tinier-update/</guid>
            <description>&lt;p&gt;Developing &lt;a href=&#34;https://github.com/jmablog/tinieR&#34;&gt;my first R package, tinieR&lt;/a&gt; was one of the most rewarding projects I&amp;rsquo;ve done this summer (and I&amp;rsquo;ve &lt;a href=&#34;https://pkc.netlify.app/&#34;&gt;been&lt;/a&gt; &lt;a href=&#34;https://squatcam.vercel.app&#34;&gt;busy&lt;/a&gt;). So much so that I couldn&amp;rsquo;t stop tinkering with it; and so now here&amp;rsquo;s tinieR 0.2.0, with added resize ability and more choice in how it returns the newly tinified file path!&lt;/p&gt;
&lt;h2 id=&#34;resizing&#34;&gt;Resizing&lt;/h2&gt;
&lt;p&gt;You can now use the &lt;code&gt;resize&lt;/code&gt; argument to change the image dimensions along with its file size. I recommend reading the &lt;a href=&#34;https://tinypng.com/developers/reference#resizing-images&#34;&gt;TinyPNG API documentation on resizing methods&lt;/a&gt; first, to familiarise yourself with the various options you can use to change image dimensions.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;resize&lt;/code&gt; takes a named list, containing a &lt;code&gt;method&lt;/code&gt; string and at least one of &lt;code&gt;width&lt;/code&gt; or &lt;code&gt;height&lt;/code&gt;, or both &lt;code&gt;width&lt;/code&gt; AND &lt;code&gt;height&lt;/code&gt; depending on your chosen resize method, to specify the dimensions in pixels you would like the image resized:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;tinify(&amp;#34;imgs/example.png&amp;#34;, resize = list(method = &amp;#34;fit&amp;#34;, width = 300, height = 150))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This should work fine alongside all existing options, like &lt;code&gt;overwrite&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;new-return_path-options&#34;&gt;New return_path options&lt;/h2&gt;
&lt;p&gt;Instead of just returning the absolute file path of the newly tinified file, you can now choose to have it returned as an absolute file path, a relative file path, or a list of the two!&lt;/p&gt;
&lt;p&gt;Set to &lt;code&gt;return_path = &amp;quot;abs&amp;quot;&lt;/code&gt; to return the absolute file path to the tinified file as before. Set to &lt;code&gt;return_path = &amp;quot;rel&amp;quot;&lt;/code&gt; to return the file path relative to the working directory &lt;strong&gt;at the time the file was tinified&lt;/strong&gt;. This may be useful if sharing a script with others across platforms, if you can be sure your project setups will be the same and you are being strict with working directories!&lt;/p&gt;
&lt;p&gt;Finally, set to &lt;code&gt;return_path = &amp;quot;all&amp;quot;&lt;/code&gt; to return both types of file path as a named list:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;shrunk_img_list &amp;lt;- tinify(&amp;#34;imgs/example.png&amp;#34;, return_path = &amp;#34;all&amp;#34;)

knitr::include_graphics(shrunk_img_list$absolute)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I hope these new options are useful - they at least seemed like things &lt;em&gt;I&lt;/em&gt; wanted when I was using the package myself! You can see full details at &lt;a href=&#34;https://github.com/jmablog/tinieR&#34;&gt;the tinieR package Github repo&lt;/a&gt; where the update is available for download now 🔥&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>tinieR 0.1.0</title>
            <link>https://jmablog.com/post/tinier-release/</link>
            <pubDate>Mon, 17 Aug 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/tinier-release/</guid>
            <description>&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; I wrote an R package. You can find it here: &lt;a href=&#34;https://github.com/jmablog/tinieR&#34;&gt;tinieR - An R package to shrink image filesizes with TinyPNG.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I learnt &lt;a href=&#34;https://www.r-project.org/&#34;&gt;R&lt;/a&gt; about a year ago to do the statistical testing for my &lt;a href=&#34;https://jmablog.com/research/pkvs&#34;&gt;dissertation&lt;/a&gt;. While borne of neccessity, it ended up kickstarting a whole coding journey for me. I&amp;rsquo;d done some dabbling in the past, but R was the first language that I felt like I really &amp;ldquo;got&amp;rdquo; and worked in a way that made sense to me, particularly with the &lt;a href=&#34;https://www.tidyverse.org/&#34;&gt;Tidyverse&lt;/a&gt; series of packages.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve since experimented with Python and JavaScript (particularly with &lt;a href=&#34;https://jmablog.com/post/posenet-app/&#34;&gt;SquatCam&lt;/a&gt;), but R will always hold a special place in my heart and be my first choice for a coding project, if possible. Looking for ways to keep progressing my skills, package development kept cropping up, and so I felt like it would be a really good way to get even more familiar with the language. The only trouble was, I didn&amp;rsquo;t really have any good ideas for things that a) I felt warranted a package and b) were within the scope of my current knowledge.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://tinypng.com/&#34;&gt;TinyPNG&lt;/a&gt; is a service I&amp;rsquo;ve been using for ages. It lets you upload PNG or JPG files and compresses them, resulting in much smaller file sizes, without any noticeable loss in image quality. I&amp;rsquo;ve used it for pretty much every image on this blog. In particular, all the graphs I like &lt;a href=&#34;https://jmablog.com/post/parkour-vault-correlation/&#34;&gt;endlessly&lt;/a&gt; &lt;a href=&#34;https://jmablog.com/post/resultant-forces/&#34;&gt;populating&lt;/a&gt; &lt;a href=&#34;https://jmablog.com/post/astronaut-mission-length-longest-v-average/&#34;&gt;my&lt;/a&gt; &lt;a href=&#34;https://jmablog.com/post/which-x-men-character-had-it-worst/&#34;&gt;posts&lt;/a&gt; with make excellent candidates for TinyPNG to shrink.&lt;/p&gt;
&lt;p&gt;After using TinyPNG for so long via their web interface, I finally decided to investigate a more economical way of using the service. They have a whole bunch of &lt;a href=&#34;https://tinypng.com/third-party&#34;&gt;third-party plugins and tools&lt;/a&gt; listed on their site that people have built. While investigating and trying out a &lt;a href=&#34;https://www.npmjs.com/package/tinypng-cli&#34;&gt;Node.js CLI&lt;/a&gt;, I realised that I knew just enough about making REST calls to APIs in R that I could potentially just code myself an integration that could run directly in my RMarkdown files for blog posts!&lt;/p&gt;
&lt;p&gt;I threw together a minimum working version of a function named &lt;code&gt;tinify()&lt;/code&gt; that took a path to an image file and sent it off to the TinyPNG API, saving the result. It worked great - well enough that it occurred to me that &lt;em&gt;other&lt;/em&gt; people might like to use it as well&amp;hellip;&lt;/p&gt;
&lt;h2 id=&#34;a-few-bumps-along-the-way&#34;&gt;A few bumps along the way&lt;/h2&gt;
&lt;p&gt;Turns out package development, even for the simplest of packages with just two actual functions, is complicated.&lt;/p&gt;
&lt;p&gt;First, as an invaluable resource, I used the &lt;a href=&#34;https://r-pkgs.org/&#34;&gt;R Packages&lt;/a&gt; book by Hadley Wickham and Jennifer Bryan extensively. It&amp;rsquo;s a great beginning-to-end guide to building a package. In particular, all the various things you need - licenses, readmes, namespaces, test, docs - are really easy to populate your package with. You still need to fill them in, but as a result, you&amp;rsquo;re far less likely to end up missing something that should be there.&lt;/p&gt;
&lt;p&gt;But, for some things, a guide can only really hold your hand so far. For example, it can tell you the mechanics of how to create a test file, what it should consist of, and how to run it, but it can&amp;rsquo;t &lt;em&gt;write the actual test&lt;/em&gt; for you, more&amp;rsquo;s the pity.&lt;/p&gt;
&lt;p&gt;Testing in particular is something I&amp;rsquo;d never done before. The &lt;a href=&#34;https://testthat.r-lib.org/&#34;&gt;testthat&lt;/a&gt; package is an amazing tool for this, and I was able to get the basics down fairly quickly. In the end, I probably went overboard on my tests - I only had the two functions, so I had the luxury of not needing to write hundreds of tests for dozens of different things. Consequently, I really tried to cover all the bases for the two lonely functions I did have. I&amp;rsquo;m proud to have reached &lt;a href=&#34;https://codecov.io/gh/jmablog/tinieR&#34;&gt;98% code coverage&lt;/a&gt; as a result though!&lt;/p&gt;
&lt;p&gt;When I was fairly happy with the state of my package, my thoughts turned to deployment. &lt;a href=&#34;https://www.rostrum.blog/2020/08/09/ghactions-pkgs/&#34;&gt;This blog post by Matt Dray&lt;/a&gt; on using &lt;a href=&#34;https://github.com/features/actions&#34;&gt;GitHub Actions&lt;/a&gt; was really useful in pointing me in the right directions to set up a continuous deployment workflow and creating an automatically generated package documentation site. While again, &lt;em&gt;probably&lt;/em&gt; overkill for this particular package, I wanted to really get to grips with the full package development experience.&lt;/p&gt;
&lt;p&gt;One particular hurdle I encountered was the need for a valid TinyPNG API key and an example image file to be present for all my behind-the-scenes package code - namely tests and R CMD checks run on deployment by GitHub Actions. I didn&amp;rsquo;t want to expose my personal TinyPNG API token to the world, so needed a way to include it without making it visible to the public. It took a little experimenting but you can &lt;a href=&#34;https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets&#34;&gt;set your API key as an encrypted secret&lt;/a&gt; on your GitHub repo, and then access it by placing it as an environment variable (env) in the workflow yaml file using ${{ secrets.SECRET_NAME }}:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;jobs:
    steps:
        name: Check
            env:
            _R_CHECK_CRAN_INCOMING_REMOTE_: false
            TINY_API: ${{ secrets.TINY_API_KEY }}
            run: rcmdcheck::rcmdcheck(args = c(&amp;#34;--no-manual&amp;#34;, &amp;#34;--as-cran&amp;#34;), error_on = &amp;#34;warning&amp;#34;, check_dir = &amp;#34;check&amp;#34;)
            shell: Rscript {0}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This environment variable is then accessed within my package code as part of the &lt;code&gt;tinify()&lt;/code&gt; function with &lt;code&gt;Sys.getenv(&amp;quot;TINY_API&amp;quot;)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As for an example image, this turned out to require putting my &lt;code&gt;example.png&lt;/code&gt; file in a sub-directory of my package named &lt;code&gt;inst/extdata&lt;/code&gt;. This file could then be accessed using &lt;code&gt;system.file(&amp;quot;extdata&amp;quot;, &amp;quot;example.png&amp;quot;, package = &amp;quot;tinieR&amp;quot;)&lt;/code&gt;. As I didn&amp;rsquo;t want to be continually overwriting this file again and again every time I tested the package, I ended up learning about &lt;code&gt;tempfile()&lt;/code&gt; and &lt;code&gt;unlink()&lt;/code&gt; as a way to create a temporary file path, copy the &lt;code&gt;example.png&lt;/code&gt; image to it, submit the temporary file to my function for testing, and then delete the temporary file.&lt;/p&gt;
&lt;p&gt;As an aside, this worked fine for clearing all my tests, but I kept getting errors when R CMD check would try and run any of this in the &amp;rsquo;examples&amp;rsquo; section of my documentation. I have to admit I never cracked this one and just ended up wrapping all my example code in my docs in &lt;code&gt;\dontrun{}&lt;/code&gt; - if anyone knows how I should be doing this, please let me know 😕&lt;/p&gt;
&lt;p&gt;After all this fiddling, getting my first &amp;lsquo;build passing&amp;rsquo; badge show up on my GitHub repo readme was one of the most satisfying feelings I&amp;rsquo;ve had in coding so far!&lt;/p&gt;
&lt;h2 id=&#34;tinier&#34;&gt;tinieR&lt;/h2&gt;
&lt;p&gt;So, here it is - &lt;a href=&#34;https://github.com/jmablog/tinieR&#34;&gt;tinieR on GitHub&lt;/a&gt; or as a pkgdown &lt;a href=&#34;https://jmablog.github.io/tinieR&#34;&gt;package documentation site&lt;/a&gt;. With it, you can shrink image file sizes with a simple call of &lt;code&gt;tinify()&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;tinify(&amp;#34;example.png&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can set options to overwrite the original file or create a new file next to it, to provide details on the amount of file size reduction and the number of API calls made this month, and to return the tinified image file path for use in other image functions. You can also combine &lt;code&gt;tinify&lt;/code&gt; with functions like &lt;code&gt;purrr::map&lt;/code&gt; and &lt;code&gt;fs::dir_ls&lt;/code&gt; to tinify entire directories at a time. Check out the links above for full details!&lt;/p&gt;
&lt;p&gt;If you find any bugs, please &lt;a href=&#34;https://github.com/jmablog/tinieR/issues&#34;&gt;let me know&lt;/a&gt;. This is my first package and I&amp;rsquo;m determined to keep learning as I try and make it the best it can be!&lt;/p&gt;
&lt;p&gt;Thanks for reading. I&amp;rsquo;ve been messing around with coding projects for a little while now - see more of them by clicking &lt;a href=&#34;https://jmablog.com/tags/coding&#34;&gt;here&lt;/a&gt;, or for posts using R specifically, &lt;a href=&#34;https://jmablog.com/tags/r&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Correlation Between Some Common Physiological Variables in Parkour Vaulting</title>
            <link>https://jmablog.com/post/parkour-vault-correlation/</link>
            <pubDate>Fri, 14 Aug 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/parkour-vault-correlation/</guid>
            <description>&lt;p&gt;In &lt;a href=&#34;https://jmablog.com/post/resultant-forces/&#34;&gt;my last blog post&lt;/a&gt;, I explored the data that resulted from my &lt;a href=&#34;https://jmablog.com/research/pkvs/&#34;&gt;undergraduate dissertation&lt;/a&gt; a little bit more. As I say in that post, I know it&amp;rsquo;s a little frowned-upon from a purely scientific point of view to double-dip on your data, but I can&amp;rsquo;t resist going back to that well.&lt;/p&gt;
&lt;p&gt;So I got curious; my dissertation focused on movement choice and landing style as factors affecting ground reaction forces (GRFs), but I&amp;rsquo;d collected a bunch of characteristic data like age, height, etc. about the participants that went mostly unused. Could any of these also play a role in how well someone mitigates their GRFs?&lt;/p&gt;
&lt;p&gt;I played about in RStudio for a while so try and explore this question. I&amp;rsquo;ve decided to stay away from much in the way of formal statistical tests in this post, and instead just tried to visualise things with a little commentary. This is mainly just to avoid anyone grabbing an offhand t-test result and declaring &amp;ldquo;tall people are statistically worse at parkour&amp;rdquo; somewhere. I just find it interesting to look at these connections (or really, as you&amp;rsquo;ll see, the lack of them) as a way to prompt questions for the future.&lt;/p&gt;
&lt;h2 id=&#34;regression-and-correlation&#34;&gt;Regression and correlation&lt;/h2&gt;
&lt;p&gt;The first subset of characteristics were continuous variables, things like age, height, etc, and so it seemed that a linear regression would be a nice, simple way to visualise how two variables may relate. I decided to focus on just vertical GRF over horizontal (for a short primer on types of GRF, check out my &lt;a href=&#34;https://jmablog.com/post/resultant-forces/&#34;&gt;resultant forces post&lt;/a&gt;), just because it&amp;rsquo;s often the most relevent to jumping and I didn&amp;rsquo;t want to completely overrun this post with plots (and I normally &lt;em&gt;love&lt;/em&gt; plots).&lt;/p&gt;
&lt;p&gt;I also chose to keep the breakdown of movement and landing style in each plot. This is how the original study ran and it made sense to me to break things down this way, to keep the data within each movement/landing style as homogeneous as possible.&lt;/p&gt;
&lt;p&gt;For each plot, the blue points are the individual data points from each participant for that movement/landing style. The red line is the linear regression, which is the straight line that best fits the data - that is, that best fits in such a way that it minimises the distance between the line and all the data points as best as possible. The fainter red area around the regression line is the standard error (SE). The narrower the SE is, the less varied the data is, which means any correlation found may be more reliable.&lt;/p&gt;
&lt;p&gt;Generally, the less &amp;lsquo;spread out&amp;rsquo; the data points around are the line as it goes either up or down, the stronger the correlation between the variables (either positively correlated if the line is going up from left to right, or negatively if it&amp;rsquo;s going down). To help with this distinction, I&amp;rsquo;ve also annotated the plots with Pearson&amp;rsquo;s &lt;em&gt;R&lt;/em&gt;, which is a numerical representation of the strength of the correlation relationship. The closer &lt;em&gt;R&lt;/em&gt; is to 1, the stronger the correlation. A hazy cloud of points means there isn&amp;rsquo;t much correlation, while a perfect line indicates a very strong correlation. The &amp;lsquo;steepness&amp;rsquo; of the line doesn&amp;rsquo;t indicate much about the correlation, but does kind of indicate how much a unit change in one variable affects the other - the steeper the line, the more a change in &lt;em&gt;y&lt;/em&gt; produced by a change in &lt;em&gt;x&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Just as an example of perfect correlation, from the parkour vaulting data - the plot below plots the participant&amp;rsquo;s weight as recorded on the force platform in Newtons against their weight calculated in kilograms. As the Newton-to-kilogram conversion is the same for each weight recorded (Newtons divided by 9.81 for earth&amp;rsquo;s gravity), they always correlate perfectly. As weight in Newtons goes up, weight in kilograms always goes up by the exact same amount. On the plot, this means a perfect 45° line of data points, an equally perfect linear regression line, and no SE shading at all.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/perfect_corr-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Of course, correlation does not mean causation, so it&amp;rsquo;s important to note any relationships found with these plots doesn&amp;rsquo;t automatically mean one causes they other; there could be many reasons for the relationship outside of the two variables under the microscope. I&amp;rsquo;ll mention that a little bit more as we go.&lt;/p&gt;
&lt;h3 id=&#34;age&#34;&gt;Age&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s start with a simple one. What effect does age have on vertical ground reaction force?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/age_v_resultbw-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;The age of participants in this study ranged from early 20s to early 40s. That&amp;rsquo;s not covering every age bracket but it was pleasingly wider than the average age of traceurs, which skews young partly because of the urban-cool imagery of the sport but also because it&amp;rsquo;s just not been around long enough for many practitioners to really get old (although we&amp;rsquo;re getting there, aren&amp;rsquo;t we? &lt;em&gt;Oh god my knees&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Age is a common enemy for athletes of all disciplines. For traceurs, the onset of osteoarthritic conditions, cartilage breakdowns, and increases in tissue healing time may present risks for joints placed under frequent high impacts, particularly in the lower body. Sarcopenia may result in the loss of muscle mass, reducing the ability of leg muscles to eccentrically absorb impacts and raising GRFs.&lt;/p&gt;
&lt;p&gt;Fortunately, from this data alone, that doesn&amp;rsquo;t seem to be kicking in for our traceurs. The SE is pretty wide for most of these, so it&amp;rsquo;s difficult to draw too many conclusions from this, but it can at least be said that no obvious relationship exists. Continued exercise and training has been shown to combat many of the detrimental effects of aging, and I see no reason to think it&amp;rsquo;s not the same for our traceurs.&lt;/p&gt;
&lt;h3 id=&#34;training-experience&#34;&gt;Training experience&lt;/h3&gt;
&lt;p&gt;If anything, the (slightly) older guys in the study had been training for longer - perhaps training experience offsets the effects of aging? Does practice really make perfect?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/yearsTraining_v_resultbw-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;No, not really.&lt;/p&gt;
&lt;p&gt;There is some, very slight, evidence of a downward trend in vGRF for the precision landing style as you gain more training experience, but weirdly the opposite for the running style landing. It&amp;rsquo;s all very weak though, and those SEs&amp;hellip;&lt;/p&gt;
&lt;p&gt;Even the least experienced traceur in this study had been practicing for 5 years. That&amp;rsquo;s still a pretty long time - you certainly couldn&amp;rsquo;t call any of the participants novices. And that&amp;rsquo;s not including any other sport or fitness experience before they started training parkour. The law of diminishing returns may be at play here, with the difference between 5 and 15 years experience being far less than might be seen between, say, 1 and 5. It would be interesting to run something similar but include much &amp;rsquo;newer&amp;rsquo; practitioners.&lt;/p&gt;
&lt;h3 id=&#34;height&#34;&gt;Height&lt;/h3&gt;
&lt;p&gt;Okay, let&amp;rsquo;s go back to some more physiological reasons. The study involved a vaulting box of a fixed height, so perhaps the various heights of the participants would interact with the height of the box differently and result in vGRF changes?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/height_v_resultbw-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Actually, maybe!&lt;/p&gt;
&lt;p&gt;There is certainly a stronger relationship seen between height and vGRF for the precision landing style, with vGRF decreasing the taller the participant. Purely as a function of distances travelled this makes sense - a shorter participant is falling a greater percentage of their overall height than a taller participant.&lt;/p&gt;
&lt;p&gt;I can also imagine that taller participants had to jump less to clear the obstacles, generating less force in their take-off and potentially resulting in an overall decrease in momentum throughout the movement that they then had to re-absorb on landing.&lt;/p&gt;
&lt;p&gt;Unfortunately, this speculation doesn&amp;rsquo;t really extend to why we don&amp;rsquo;t see the same relationship in the running style landing. The best I can think of is that there is a key biomechanical difference between two-leg and single-leg landings. Studies have found flexion at the knee is drastically lessened in single-leg landings. Does this even the playing field? Are taller traceurs actually &lt;em&gt;mechanically&lt;/em&gt; better at absorbing GRFs due to the longer levers of their leg? And so if the ability to flex at the knee is taken away or reduced, they can&amp;rsquo;t benefit from it as much?&lt;/p&gt;
&lt;p&gt;This one stumped me a bit. I&amp;rsquo;d be curious to hear if anyone out there has any thoughts.&lt;/p&gt;
&lt;h3 id=&#34;weight&#34;&gt;Weight&lt;/h3&gt;
&lt;p&gt;Well this one should be obvious. The heavier you are, the more GRF you should be generati-&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/weightKg_v_resultbw-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Huh.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not all that strong, but there seems to be a &lt;strong&gt;negative&lt;/strong&gt; correlation here. That is, the heavier you are, the &lt;em&gt;less&lt;/em&gt; vGRF you produce. What?&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s worth noting that the force readings for this study (and all these plots) were &lt;em&gt;standardised&lt;/em&gt; to multiples of bodyweight (BW). &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Weight and force were both initially measured in Newtons on a force platform. So, if one participant landed with a force of 600 Newtons, and they weighed 600 Newtons, they got a result of 1 x BW for that landing (600 / 600). If they landed at 1200 Newtons, they got 2 x BW (1200 / 600).&lt;/p&gt;
&lt;p&gt;If someone weighing 1000 Newtons landed with a force of 1000 Newtons, they also got a result of 1 x BW (1000 / 1000). Generally, 1 x BW is the force you&amp;rsquo;ll be exerting on a force platform if you are just standing still on it.&lt;/p&gt;
&lt;p&gt;So, in this plot, the heavier participants towards the right of the &lt;em&gt;x&lt;/em&gt; axis are most likely still landing with more &lt;em&gt;absolute&lt;/em&gt; force - that is, higher Newtons. You can see that if I take the previous plot and change the force units on the &lt;em&gt;y&lt;/em&gt; axis back to Newtons:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/weightKg_v_resultn-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s that mostly upward trend we were expecting before. A good demonstration of why the units in a plot matter!&lt;/p&gt;
&lt;p&gt;Still, it&amp;rsquo;s interesting to note that the heavier participants in this study were landing with &lt;em&gt;lower multiples of their own bodyweight&lt;/em&gt;, or lower &lt;em&gt;relative&lt;/em&gt; force. Perhaps they were heavier because they were more muscular, and better able to absorb their GRFs? Maybe they were heavier because they were &lt;em&gt;taller&lt;/em&gt;, and therefore actually we&amp;rsquo;re just seeing another version of the height plot above? Oh no, now I have to go back and look at that plot again&amp;hellip;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a good example of why you can&amp;rsquo;t take variables in isolation, and why it&amp;rsquo;s so hard to conlusively prove the effect of some interventions. You have to control for these things and try and tease apart the relationships to make sure you aren&amp;rsquo;t just measuring the same thing twice!&lt;/p&gt;
&lt;h3 id=&#34;vertical-and-horizontal-grf&#34;&gt;Vertical and horizontal GRF&lt;/h3&gt;
&lt;p&gt;I was also curious, are the vertical and horizontal braking parts of a GRF correlated themselves? After all, in the &amp;lsquo;real world&amp;rsquo;, they&amp;rsquo;re really just components of a larger &lt;a href=&#34;https://jmablog.com/post/resultant-forces/&#34;&gt;resultant force&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Plotting them against each other gives us this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/correlation-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;It varies from movement to movement, but there is some mid-to-strong correlation between the two for precision landings, with weaker correlation for running landings.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re coming to a complete stop with a landing, you&amp;rsquo;re applying the brakes in both directions - vertically and horizontally. So it makes sense that they would kind of sync up - the harder a landing, the greater force in both directions the ground will produce to deal with it and bring you to a stop. With a running landing, you are trying to arrest your downwards vertical motion, but &lt;em&gt;not&lt;/em&gt; your horizontal motion - if anything you&amp;rsquo;re doing the opposite and trying to minimise horizontal braking entirely to avoid slowing down. This desyncs the goals for vertical and horizontal GRF production, reducing their correlation.&lt;/p&gt;
&lt;p&gt;It might be interesting to see if there&amp;rsquo;s a resulting correlation between vertical and propulsive horizontal force instead in running landings. I don&amp;rsquo;t have that data to hand but it could be worked out from the raw force platform data collected for the dissertation project. I may come back to it, or if &lt;a href=&#34;https://figshare.com/articles/Parkour_Vault_Research/12231089/1&#34;&gt;anyone out there wants some homework&lt;/a&gt;&amp;hellip;&lt;/p&gt;
&lt;h3 id=&#34;landing-foot&#34;&gt;Landing foot&lt;/h3&gt;
&lt;p&gt;Finally, moving away from regression and correlation a bit, I also asked participants which landing foot they preferred to land on for single foot landings. Would this make a difference to vGRFs?&lt;/p&gt;
&lt;p&gt;This one just involved two categories, left foot or right foot, so a correlation/regression plot wouldn&amp;rsquo;t work, so this one is a boxplot with a simple &lt;em&gt;t&lt;/em&gt;-test performed between the two groups (annotated by the lines at the top of each plot square).&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/preferredFoot-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Sometimes, lefties did better, and sometimes righties did. But, there was never a significant difference between their results. And good thing too! Otherwise, we&amp;rsquo;d be teaching everyone to land on the same foot all the time. This was one plot I was happy to find absolutely nothing worthwhile in.&lt;/p&gt;
&lt;p&gt;Of course, it would still be interesting to see how performance differs between their &lt;em&gt;own&lt;/em&gt; two feet for traceurs&amp;hellip; But that&amp;rsquo;s another study for another time.&lt;/p&gt;
&lt;p&gt;Thanks for reading. If you enjoy this kind of nerdy deep dive on parkour movement, you can check out the original study this data came from &lt;a href=&#34;https://jmablog.com/research/pkvs&#34;&gt;here&lt;/a&gt; and even grab the data for yourself if you would like to perform your own analysis. You can also view the source code for all the plots in this post &lt;a href=&#34;https://github.com/jmablog/jmablog-code-snippets/blob/master/correlation-in-parkour-vaulting/correlation-in-parkour-vaulting.Rmd&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;You can see this in the plot at the start of this post showing perfect correlation, because weight in Kg and weight in Newtons are just measuring the exact same thing.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        
        <item>
            <title>Parkour Clinic Launches!</title>
            <link>https://jmablog.com/post/parkour-clinic-launch/</link>
            <pubDate>Wed, 05 Aug 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/parkour-clinic-launch/</guid>
            <description>&lt;p&gt;After a few long months of planning and preparation, and some not-inconsiderable beauracratic wranglings, I&amp;rsquo;m happy to finally launch a new project: the &lt;a href=&#34;https://pkc.netlify.app/&#34;&gt;Parkour Clinic&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Ever since graduating as a sports therapist earlier this year, I&amp;rsquo;ve been looking for something to do that used my hard-won therapy skills, but more importantly was also &lt;strong&gt;useful&lt;/strong&gt;. I&amp;rsquo;m going to continue studying with a Masters degree starting in October 2020, but until then, the plan initially had been to fill my summer months by looking for some actual real work treating real patients. You know, like a real sports therapist, which I am now. &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, my graduation turned out to be bang in the middle of the covid-19 / coronavirus pandemic, and so setting up (or joining) an in-person sports therapy clinic became&amp;hellip; somewhat impractical. Besides, even at the best of times, setting up my own clinic would involve a potentially large investment. So, I started looking into options for delivering therapy remotely.&lt;/p&gt;
&lt;p&gt;It turns out this is a solution that the sports therapy (and physiotherapy) world is exploring more and more. The increasing focus on patient education and exercise prescription over hands-on therapies like massage means that a lot of effective therapy advice and guidance can be delivered over a webcam. &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; This allows therapists to reach a much wider audience and potentially help a lot more people than just those who can physically attend a clinic session. And, delightfully, most of the things you need - a website, a booking system, and a video calling platform - can be setup for free these days. &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Parkour has played a big role in my life, changing my career, social circle, and health. It did all this, basically, for free. So once I realised the cost to myself would be minimal, and could be run in my spare time, offering an online sports therapy service for the parkour community &lt;strong&gt;that was also free&lt;/strong&gt; seemed a good way to give back to something that has given me so much. Once I had the idea, I couldn&amp;rsquo;t at least &lt;em&gt;try&lt;/em&gt; it.&lt;/p&gt;
&lt;h2 id=&#34;parkour-clinic&#34;&gt;Parkour Clinic&lt;/h2&gt;
&lt;p&gt;So here it is - &lt;a href=&#34;https://pkc.netlify.app/&#34;&gt;Parkour Clinic&lt;/a&gt;, offering free online sports injury therapy advice for parkour athletes.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://pkc.netlify.app/&#34;&gt;&lt;img src=&#34;pkc-site.png&#34; alt=&#34;&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I recommend checking out the clinic &lt;a href=&#34;https://pkc.netlify.app//faq&#34;&gt;FAQ&lt;/a&gt; for more detailed information on how it works, what sports therapy is, and how it can help you. And, you can always &lt;a href=&#34;https://pkc.netlify.app//contact&#34;&gt;send me a message&lt;/a&gt; if you have any questions not answered on the site.&lt;/p&gt;
&lt;p&gt;You can also connect on social media if that&amp;rsquo;s your cup of tea, with &lt;strong&gt;@parkourclinic&lt;/strong&gt; on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;i class=&#34;fab fa-twitter&#34;&gt;&lt;/i&gt; &lt;a href=&#34;https://twitter.com/parkourclinic&#34;&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;i class=&#34;fab fa-instagram&#34;&gt;&lt;/i&gt; &lt;a href=&#34;https://www.instagram.com/parkourclinic/&#34;&gt;Instagram&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please consider sharing word of Parkour Clinic with your friends and parkour community!&lt;/p&gt;
&lt;p&gt;And when you&amp;rsquo;re ready to make your appointment, &lt;strong&gt;&lt;a href=&#34;https://pkc.netlify.app//book&#34;&gt;book now&lt;/a&gt;&lt;/strong&gt; and I look forward to speaking to you soon!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Still doesn&amp;rsquo;t quite feel real after studying it for so long!&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I&amp;rsquo;m grateful to the likes of &lt;a href=&#34;https://www.thesports.physio/&#34;&gt;Adam Meakins&lt;/a&gt; and the &lt;a href=&#34;https://www.betterclinicianproject.com/&#34;&gt;Better Clinician Project&lt;/a&gt; for opening my eyes to the possibilities of this approach.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;With the trade-off usually being the time and knowledge you invest in it - I did a &lt;em&gt;lot&lt;/em&gt; of research setting up with the right tools, and building the website by hand instead of using a pre-built host like Squarespace. Buying off-the-shelf solutions might cost you, but it sure is quicker.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        
        <item>
            <title>Resultant Forces in Parkour Vaults</title>
            <link>https://jmablog.com/post/resultant-forces/</link>
            <pubDate>Tue, 04 Aug 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/resultant-forces/</guid>
            <description>&lt;p&gt;I had a lot of ideas for what I wanted to include in my &lt;a href=&#34;https://jmablog.com/research/pkvs&#34;&gt;dissertation&lt;/a&gt;. Starting out, writing my proposal, I wanted to look at &lt;em&gt;everything&lt;/em&gt; I could think of in relation to vaulting in parkour and the landing forces that result. I wanted to include &lt;a href=&#34;https://www.scienceforsport.com/rate-of-force-development-rfd-2/&#34;&gt;rate of force development&lt;/a&gt;, projectile motion of bodies in the air, motion tracking joint angles&amp;hellip; Every biomechanical variable you could think of, I wanted it in there.&lt;/p&gt;
&lt;p&gt;Unfortunately, the more variables you start throwing in, the more diluted your study becomes. It&amp;rsquo;s hard to tell a good story about so many outcomes! The best scientific studies I&amp;rsquo;ve read have picked one variable and really &lt;em&gt;gone in&lt;/em&gt; on what it is, what it means, and why you should care about it. There&amp;rsquo;s also a &lt;em&gt;lot more&lt;/em&gt; statistical work involved with more variables, and frankly for undergrad level it was overkill. So I drilled down, and went with what I considered the essential.&lt;/p&gt;
&lt;p&gt;As a side effect, I ended up with a lot of research and ideas on the cutting room floor. As the final study is done and dusted, it seemed a shame to throw the data out with it. I get that&amp;rsquo;s how strict science is supposed to work; hypothesis, gather data, test hypothesis, &lt;strong&gt;done&lt;/strong&gt;. But I&amp;rsquo;m not writing a second paper with it; I just want to poke and prod it a little to get some ideas.&lt;/p&gt;
&lt;p&gt;Plus I like making graphs.&lt;/p&gt;
&lt;p&gt;One discarded idea that really stuck with me was an investigation into the &lt;strong&gt;resultant landing forces&lt;/strong&gt; that people experience when landing from parkour vaults. So I decided to dig into it further. I wanted to share some of these observations, but that&amp;rsquo;s all they are. I haven&amp;rsquo;t done any in-depth statistical testing here. But, resultant forces present a really interesting way to visualise the forces acting upon a body when landing from a movement, particular one that doesn&amp;rsquo;t just involve jumping straight up and down, but involves a horizontal travelling component.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s jump in, but first&amp;hellip;&lt;/p&gt;
&lt;h2 id=&#34;what-is-a-landing-or-ground-reaction-force&#34;&gt;What is a landing (or ground reaction) force?&lt;/h2&gt;
&lt;p&gt;Most people are at least vaguely familiar with &lt;a href=&#34;https://en.wikipedia.org/wiki/Newton%27s_laws_of_motion#Newton&#39;s_third_law&#34;&gt;Newton&amp;rsquo;s Third Law of Motion&lt;/a&gt; - often summarised as &amp;lsquo;for every action there is an equal and opposite reaction&amp;rsquo;. When it comes to landing, this means that the floor &amp;lsquo;pushes&amp;rsquo; back on you exactly as hard as you push upon it. It has to; if it couldn&amp;rsquo;t match your force in coming down, you&amp;rsquo;d smash straight through the floor. This force is called the &lt;strong&gt;ground reaction force&lt;/strong&gt; (GRF), which makes sense, as it&amp;rsquo;s the &lt;em&gt;force&lt;/em&gt; the &lt;em&gt;ground&lt;/em&gt; is &lt;em&gt;reacting&lt;/em&gt; to you with. Sometimes science comes up with really hard, confusing names for things, and sometimes it&amp;rsquo;s just like &amp;lsquo;yeah, just call it exactly what it is&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;Anyway, if jumping straight up and down, it looks like this, with the green arrow as the force your landing is exerting, and the red arrow as the GRF:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;vGRF.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;This is generally known as &lt;strong&gt;vertical&lt;/strong&gt; GRF.&lt;/p&gt;
&lt;p&gt;The strength (or &lt;strong&gt;magnitude&lt;/strong&gt;) of the forces at play depends upon a few things, such as your bodyweight, the speed you are travelling, and how much you are able to actively mitigate the impact you make. The final one is pretty much what I studied in the dissertation and one of the things people are most interested in with parkour - the ability to absorb and reduce some of these landing forces using good technique and strong leg muscles. Some people can land really softly, and some people can come down like a sack of bricks, despite weighing the same and dropping the same distance.&lt;/p&gt;
&lt;p&gt;As well as jumping straight up and down, sometimes you jump forward and backward, or side to side. These movements have their own GRFs, corresponding to the direction you are moving. Again this makes sense - the ground has to stop you from continuing to move forward if you do a broad jump, otherwise you&amp;rsquo;d land and continue to slide forward forever until you met another obstacle. While hilarious, this would be impractical.&lt;/p&gt;
&lt;p&gt;While side to side (or medial-lateral) GRF is useful for things like studying balance, I just looked at forward-backward (or anterior-posterior, or just &lt;strong&gt;horizontal&lt;/strong&gt;) GRF alongside vertical. Here&amp;rsquo;s a diagram of horizontal GRF acting as a braking force to slow you down:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;hGRF.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;One interesting note here is that horizontal GRF also applies to activities like walking or running, and has two sub-divisions. Braking GRF is when the ground is stopping you from carrying on; if you&amp;rsquo;re coming to a dead stop after a movement, this is all that will affect you. But if you&amp;rsquo;re continuing to move forward in some way after landing, you also use propulsive GRF to push off the floor and accelerate. Suddenly, the ground isn&amp;rsquo;t pushing back on you to slow you down, but pushing you forwards:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;running.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;The interplay of braking and propulsive forces is what allows us to walk, run, and sprint. This comes up when it comes to landing from a vault with a running landing. We&amp;rsquo;ll get there a little bit later.&lt;/p&gt;
&lt;h2 id=&#34;so-whats-a-resultant-force-here&#34;&gt;So what’s a resultant force here?&lt;/h2&gt;
&lt;p&gt;So, we have vertical and horizontal as two directions of GRF commonly studied by sports scientists. But when you&amp;rsquo;re coming in to land from a broad jump or a vault, you&amp;rsquo;re often not just coming straight down, or sliding along the ground perfectly horizontally. You are moving in a &lt;em&gt;combination&lt;/em&gt; of up-and-down, &lt;em&gt;and&lt;/em&gt; forward-and-backward directions. The force you are exerting on the ground isn’t really split two distinct parts, even though it&amp;rsquo;s often studied in this way, but is actually a single force coming in at an angle. For our uses, the resultant landing force is therefore the &lt;strong&gt;combination of the vertical and horizontal GRFs acting upon you when landing&lt;/strong&gt;, reflecting the kind-of-real-world-equivalent force you&amp;rsquo;re experiencing.&lt;/p&gt;
&lt;p&gt;To illustrate, if you&amp;rsquo;re landing like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;landing.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;GRFs don&amp;rsquo;t push back upon you in separate vertical and horizontal stages, like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;notRF.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;They match not only the &lt;em&gt;magnitude&lt;/em&gt; of the combination of the forces, but also the &lt;em&gt;angle&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;rf.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;This presents a fairly intuitive way to visualise the forces acting upon you when landing in any movement that isn&amp;rsquo;t just straight up-and-down. So, much like dealing with solely vertical or horizontal GRF, we can use the resultant GRF to determine the effect that a landing will have on you.&lt;/p&gt;
&lt;p&gt;As an aside, you might wonder why GRFs are normally decomposed into separate vertical and horizontal components. Well, it&amp;rsquo;s just generally easier to analyse, and there&amp;rsquo;s usually more of a direct relation between one component and the movement being carried out. You might be more concerned with horizontal GRFs for a sport like sprinting where there isn&amp;rsquo;t as much up-and-down movement and acceleration is &lt;em&gt;really&lt;/em&gt; important, so you focus there and leave vertical GRFs out to present a clearer picture of your area of interest. Jumping is usually up-and-down more than horizontal, so the focus is on vertical GRF. Parkour joins sports like gymnastics and dance where a combination of vertical and horizontal motion mean resultant forces might be something worth looking at more than the individual components.&lt;/p&gt;
&lt;h2 id=&#34;why-look-at-landing-forces-at-all&#34;&gt;Why look at landing forces at all?&lt;/h2&gt;
&lt;p&gt;Generally, the larger the magnitude of GRF you experience, the more stress is passed on to the body, and the greater your chance of an injury from that movement. It&amp;rsquo;s not always cut-and-dry, there are a lot of other factors that can go into it, but basically we know that larger GRF on landing is more demanding of the body to deal with, and more likely to hurt you in some fashion than a smaller GRF.&lt;/p&gt;
&lt;p&gt;Since the exact amount of GRF you&amp;rsquo;ll experience varies a lot throughout the stages of a landing, generally we look at the &lt;strong&gt;peak&lt;/strong&gt; amount, or largest magnitude value we can identify during the landing. In investigating these forces, I found that vertical GRF plays a much more influential role in the magnitude of peak resultant GRF than horizontal does; that is, peak vertical GRF is usually much larger than the peak horizontal GRF and so peak resultant GRF occurs mostly around the same time as peak vertical.&lt;/p&gt;
&lt;p&gt;With resultant forces, we can also look at the angle that the GRF is applying itself to you, and mostly here I&amp;rsquo;ve looked at the angle that peak resultant GRF occurs. 0° is flat, and 90° is straight up, so any resultant angle lower than 90° means that the peak occurred during braking, and angles beyond 90° mean peak occurred during propulsion.&lt;/p&gt;
&lt;p&gt;Here, I&amp;rsquo;ve looked at angle with just interested observations. I haven&amp;rsquo;t gone in depth on the subject (yet), but since &lt;a href=&#34;https://en.wikipedia.org/wiki/Shear_force&#34;&gt;shearing forces&lt;/a&gt; are a thing, it&amp;rsquo;s easy to imagine that the angle a GRF acts upon your tissues could also play a role in injury.&lt;/p&gt;
&lt;h2 id=&#34;calculating-and-plotting-resultant-forces&#34;&gt;Calculating and plotting resultant forces&lt;/h2&gt;
&lt;p&gt;I won&amp;rsquo;t go into a lot of detail here; you can find a really good breakdown on how to calculate resultant forces in &lt;a href=&#34;https://www.phyley.com/find-resultant-force&#34;&gt;this article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The nice thing about working with purely vertical and horizontal GRFs is that we know what the angles for each are always going to be. Vertical GRF will be 100% of the force at 90° and 0% at 0°, and horizontal will be vice versa. We don&amp;rsquo;t need to further break down the &lt;em&gt;x&lt;/em&gt; and &lt;em&gt;y&lt;/em&gt; components of each force. This means we can simplify our calculations to work out resultant from vertical and horizontal GRFs to just the following (in &lt;a href=&#34;https://www.r-project.org/&#34;&gt;R&lt;/a&gt;):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;resultant_magnitude = sqrt(Horizontal_GRF^2 + Vertical_GRF^2)
resultant_angle = (atan2(Vertical_GRF, Horizontal_GRF) * 180 / pi)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Applying this to all the GRFs in the &lt;a href=&#34;https://github.com/jmablog/parkour-vault-research&#34;&gt;force platform data I collected&lt;/a&gt;, it&amp;rsquo;s then quite easy to just filter for the peak value with &lt;code&gt;max(resultant_magnitude)&lt;/code&gt;, also grabbing the angle and vertical / horizontal GRFs at the time when that peak occurs. When it comes to plotting, we can then just use the horizontal GRF as our &lt;em&gt;x&lt;/em&gt; co-ordinate, and the vertical GRF as our &lt;em&gt;y&lt;/em&gt; component, provided we make sure the plotting grid has a 1-1 ratio for &lt;em&gt;x&lt;/em&gt; and &lt;em&gt;y&lt;/em&gt; co-ordinates. You can do this in R and ggplot2 with &lt;code&gt;coord_fixed()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Et voila! We can now view our resultant force data in a variety of ways.&lt;/p&gt;
&lt;h2 id=&#34;finally-the-point&#34;&gt;Finally, the point&lt;/h2&gt;
&lt;p&gt;I wanted to get a broad overview of the resultant forces in parkour vaults first. There were 10 participants in the study, and each performed 3 repetitions of every movement with each landing style.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; if you haven&amp;rsquo;t read the &lt;a href=&#34;https://jmablog.com/research/pkvs/&#34;&gt;original study&lt;/a&gt; for this data, the movements performed were a drop landing, a step vault, a kong vault, and a dash vault. The landing styles were a precision landing, with two feet coming to a stop, and a running landing, with one foot and continuining into a run. Force readings were normalised to bodyweight (BW), to allow comparisons between people that weigh different amounts. Generally, 1 BW is the GRF you experience standing upright and still on the ground, as a result of gravity. The GRF figures for precisions landings were also halved to give the GRFs passing through a single limb, to match with the running landing.&lt;/p&gt;
&lt;p&gt;Taking the mean of all 3 reps, and then the mean for all 10 participants, for all movement/landing style combinations gave the following:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/avg_for_all-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;You can view this plot (and all that follow) as if the participant was coming in to land from the top right of each square; the arrow indicates the direction and magnitude of the resultant GRF pushing back upon the participant as they hit the floor. For the Horizontal / &lt;em&gt;x&lt;/em&gt; component of the plot, positive numbers indicate braking, while negative are propulsive. Like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/avg_for_all-2.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;(Definitely not to scale)&lt;/p&gt;
&lt;p&gt;You can see a couple things straight away from this plot. Resultant GRF magnitudes increase with a running landing compared to a precision landing. This agrees with my findings in the original study about vertical GRF, and given the dominance of vertical GRF in calculating the peak resultant force, makes sense.&lt;/p&gt;
&lt;p&gt;Resultant angles were all below 90° for precision landings, and all above 90° for running landings. This means peak resultant GRF occurred during braking for precisions, and during propulsion for running landings. This also makes sense, as you&amp;rsquo;re coming to a stop with a precision but continuing forwards with a run. Still, it&amp;rsquo;s good to note that the greatest GRF occurred because the participant was accelerating, and actively pushing on the ground, rather than during the initial period of landing. More on this later.&lt;/p&gt;
&lt;p&gt;Alright, what if we try looking at individual participants? Do the resultant forces depend a lot on the person, or are they consistent regardless of who performs them?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/avg_plus_all_reps_all_participants-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Okay! So, it looks to me like precision landings produce a more consistent resultant force overall, with running landings have a lot more variation in resultant angle. There&amp;rsquo;s a pretty weird single arrow sticking off in the drop / running group, but otherwise the observations from the group averages stand. There&amp;rsquo;s an increase in magnitude when switching to a running landing, and running landings tends to be a bit more anteriorly (forward) shifted in their peak resultant force angles.&lt;/p&gt;
&lt;p&gt;Can we get a broad overview of how this breaks down per partcicipant for each movement and landing style?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/all_participants_all_movements_precision_landing_style-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Yes! Although a bit harder to see as it&amp;rsquo;s zoomed out quite far, this plot shows each participant as a column, and each movement as a row. The red arrows show the average values we&amp;rsquo;ve been looking at so far, but the fainter blue arrows show the actual results from each individual rep that the participant performed. By seeing how much blue shows up, and how far apart the blue arrows are from each other, we can get a sense of how much the repetitions varied from each other for that participant and movement.&lt;/p&gt;
&lt;p&gt;Just scanning your eye over it, you can get a sense for the general direction the arrows are taking for all precision landings - all posterior, or less than 90° from horizontal. There isn&amp;rsquo;t a lot of blue showing, indicating mostly consistent results per participant, although partly that could be because of the zoomed out scale. Still, the movement that seems to produce the most blue arrows is the kong; let&amp;rsquo;s make a note of that.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the equivalent for running landings:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/all_participants_all_movements_running_landing_style-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Again, just scanning over the plot, you can get a sense of the general direction of the arrows; a lot more straight up or anteriorly orientated, at or beyond 90° from horizontal. This matches what we saw in the averages plot earlier. There&amp;rsquo;s also more blue showing up in the kong again&amp;hellip;&lt;/p&gt;
&lt;p&gt;We could start drilling down into each movement or landing style individually, but I don&amp;rsquo;t want this post to become a novel. We&amp;rsquo;ve seen the most blue showing up for the kong, in both precision and running landings. Let&amp;rsquo;s take a closer look at that.&lt;/p&gt;
&lt;p&gt;Here, I&amp;rsquo;ve plotted the average resultant force in red for each participant (1-10) performing a kong with a running landing, and also included in blue the actual values recorded for each of the 3 reps they performed, similar to the previous plots. I&amp;rsquo;ve also added back in the peak resultant force magnitude and angle in text annotation:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/unnamed-chunk-2-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d say a good 7 out of the 10 participants were actually quite consistent in their execution here. Shout out to number 9 in particular; you can barely even see the blue arrows for each rep, they&amp;rsquo;re so tightly grouped. Nice.&lt;/p&gt;
&lt;p&gt;Notably the participants with the more variable results also produced a more posteriorly (backward) title arrow; that is, close to or less than 90°. They still had individual reps beyond 90°, but the average was pulled backwards.&lt;/p&gt;
&lt;p&gt;How does this compare to a kong with a precision landing?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/unnamed-chunk-3-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Everyone is a lot more consistent here, and &lt;em&gt;all&lt;/em&gt; the angles are at or below 90°.&lt;/p&gt;
&lt;p&gt;This is all very interesting, but it&amp;rsquo;s starting to lead to the question - if the peak magnitude for a resultant force with a running landing happens during propulsion, what is the actual peak magnitude for the &lt;em&gt;landing&lt;/em&gt; part of a running landing?&lt;/p&gt;
&lt;p&gt;For that, we need a way to separate out the landing part of the movement from the, well, running part. That&amp;rsquo;s difficult to do with peak values. We could try and delineate parts of the movement based on time but, well, it gets tricky standardising individual movements to the same timeline (some people land quickly, some people take longer). Luckily we&amp;rsquo;re not after hard statistical number-science here; there&amp;rsquo;s a nice visual way to look at these things.&lt;/p&gt;
&lt;h2 id=&#34;force-profiles&#34;&gt;Force profiles&lt;/h2&gt;
&lt;p&gt;With the force platform data I collected, it&amp;rsquo;s possible to plot the actual millisecond-by-millisecond changes in horizontal and vertical force readings as &lt;em&gt;x&lt;/em&gt; and &lt;em&gt;y&lt;/em&gt; components, and then connect them up to form a path of resultant forces throughout a movement. The plots get a little messy, as you&amp;rsquo;ll see, but it summarises the directions and magnitudes of forces acting on the body (in the vertical and horizontal axes, as least) quite nicely. Here is an example plot for one participant, with one rep. We&amp;rsquo;ve been looking at kongs with running landings, so let&amp;rsquo;s also stick with that:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/mapped_force_profiles-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;It gets a little muddy due to the sheer number of data points, but I&amp;rsquo;ve tried marking little blue arrows to indicate the direction the forces are moving in throughout the movement. Each arrow occurs at 1 millisecond, so the more spread out the arrows are, the quicker the force is changing.&lt;/p&gt;
&lt;p&gt;You can see that the force first spikes hard to the right (so, backwards) at the start, when the foot first makes contact with the floor and braking begins. It then loops back round and down, before moving to the left (or forwards) and back up as the participant weight shifts over the midfoot and the propulsion phase of the running landing begins. This is where peak resultant force occurs - at the highest point on the plot, which you can see is to the left of 0 on the &lt;em&gt;x&lt;/em&gt; axis and therefore in the propulsive phase.&lt;/p&gt;
&lt;p&gt;This lets us try and answer our question from before; in this one example, the peak &lt;em&gt;landing&lt;/em&gt; resultant force (that first spike to the right) appears to be less than the &lt;em&gt;absolute&lt;/em&gt; peak resultant force (that second spike on the left), albeit not by a lot. This is just one rep by one participant though; what if we widen things back out to the whole study?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plots/unnamed-chunk-4-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Again it&amp;rsquo;s little tricky to show fine detail in these plots due to the density of data and zoomed out perspective, but scanning your eye over the results here gives a sense of what we&amp;rsquo;d started to suspect. For precision landings, there is nearly always that general tilt to the right that indicates most of the GRFs are occurring with a posterior orientation. And, tellingly, that sharp spike to the right on first landing appears to also be where the peak force magnitude occurs, with most of the rest of the movement not surpassing it, or at least not by much.&lt;/p&gt;
&lt;p&gt;However, in running landings, that landing spike often &lt;em&gt;isn&amp;rsquo;t&lt;/em&gt; the largest force seen, sometimes only by a bit, but sometimes by quite a large margin. Look at the running landing for participant 6; the landing spike is not even much above 1 x bodyweight, but the peak force occuring towards the left is way up at over 4 x bodyweight!&lt;/p&gt;
&lt;h2 id=&#34;so-what-have-we-learned&#34;&gt;So what have we learned?&lt;/h2&gt;
&lt;p&gt;A couple of general observations can be made in all this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;peak resultant force magnitudes increase in running style landings&lt;/li&gt;
&lt;li&gt;they also tend to be more anteriorly orientated at the time of peak magnitude&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since peak force, regardless of when it occurs during execution of a landing / movement, is a key measure of stress on the body, looking at peak resultant forces in general remains interesting and, I believe, relevant. But, mapping them out visually in the way I&amp;rsquo;ve done here raises some questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;does the peak resultant force in a running style landing occur as a result of absorbing the landing, or from pushing back off the ground to accelerate and continue moving?&lt;/li&gt;
&lt;li&gt;does this matter? Is it worth isolating the phases of a running landing when comparing to other landing styles? Or should we be including propulsive phases when investigating other landing styles, such as a precision landing into a plyometric jump?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This could be something fairly unique to parkour; I struggle to think of another physical activity or sport besides dance that could involve landing from some significant height on one leg before continuing into a run. I plan to continue my research into the biomechanics of parkour; I&amp;rsquo;m doing a Masters by Research next year in fact. So who knows. Maybe all this poking and prodding of old data will lead to something amazing in a full investigation.&lt;/p&gt;
&lt;p&gt;Thanks for reading. If you enjoy this kind of nerdy deep dive on parkour movement, you can check out the original study this data came from &lt;a href=&#34;https://jmablog.com/research/pkvs&#34;&gt;here&lt;/a&gt; and even grab the data for yourself if you would like to perform your own analysis. You can also view the source code for all the plots in this post &lt;a href=&#34;https://github.com/jmablog/jmablog-code-snippets/blob/master/resultant-forces/resultant-forces.Rmd&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Dissertation summary slides</title>
            <link>https://jmablog.com/post/pkvs-slides/</link>
            <pubDate>Wed, 29 Jul 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/pkvs-slides/</guid>
            <description>&lt;p&gt;If you don&amp;rsquo;t have the time, energy, or stomach to read all 6000+ words of my &lt;a href=&#34;https://jmablog.com/research/pkvs&#34;&gt;full dissertation&lt;/a&gt; (and frankly, who can blame you), I&amp;rsquo;ve put up some short summary slides:&lt;/p&gt;
&lt;p&gt;&amp;#x26a1; &lt;a href=&#34;https://jmablog.com/research/pkvs/slides&#34;&gt;View summary slides&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;These were written in &lt;a href=&#34;https://remarkjs.com/&#34;&gt;Remark&lt;/a&gt; and so should work in the browser, even on mobile. Just click or swipe through.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>A facsimile of an electrotherapy machine</title>
            <link>https://jmablog.com/post/electrotherapy-app/</link>
            <pubDate>Sun, 26 Jul 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/electrotherapy-app/</guid>
            <description>&lt;p&gt;Around the beginning of March was a strange time at university. The Covid-19 pandemic was rumbling in the distance, but it wasn&amp;rsquo;t quite real yet. Posters about washing your hands started cropping up in the uni bathrooms. Emergency plans were being discussed, but they weren&amp;rsquo;t really believed to be necessary. Everyone expected things to carry on as normal.&lt;/p&gt;
&lt;p&gt;We all left on Friday 6th of March for reading week, and never went back.&lt;/p&gt;
&lt;p&gt;Things became very real very quickly that week, and the university (wisely) took the initiative and closed campus, before even the offical country wide lockdown was announced. Lectures moved online, and as lockdown increasingly stretched out in front of us all, it became clear that assessments would need to move online too.&lt;/p&gt;
&lt;p&gt;We were lucky, mostly, on the Sports Therapy course, as many of our remaining assessments could move online without much disruption. You can submit dissertations online, you can have viva exams over video calls. We didn&amp;rsquo;t have any formal written exams left, the kind that usually require you to sit in an exam hall to make sure you&amp;rsquo;re not just googling each question as you get to it.&lt;/p&gt;
&lt;p&gt;Unfortunately, one practical exam remained, for &lt;a href=&#34;http://www.electrotherapy.org&#34;&gt;electrotherapy&lt;/a&gt; (the delivery of ultrasound, interferential, or similar treatments). These treatments require a therapist to correctly setup a machine to deliver the appropriate desired effect (intensity, duration, tissue depth, things like that). The viva component of the exam - explaining why you&amp;rsquo;re doing what you&amp;rsquo;re doing for a given injury - could be done on video. The actual physical delivery is not complicated enough to require much assessment, it&amp;rsquo;s just applying some pads or moving an ultrasound head around the area (besides, our clinical skills for things like ensuring patient comfort, had already been assessed in a manual therapy exam).&lt;/p&gt;
&lt;p&gt;But how do you test the ability of a student to correctly setup a machine to deliver a chosen modality if they&amp;rsquo;re not standing in front of it? The best we could do was pretend, and just talk through the settings we&amp;rsquo;d pick as if we had a machine in front of us.&lt;/p&gt;
&lt;p&gt;Listening to my lecturer talk about the exam, it occurred to me that really all that was taking place was a series of menu selections. The exam isn&amp;rsquo;t testing if you can correctly press buttons on a machine - it&amp;rsquo;s testing that you can &lt;em&gt;pick the right option&lt;/em&gt; from a given selection, for all the variables you might change when delivering an electrotherapy treatment. Talking this through without a machine in front of me was going to be brain-bending. So I needed a way to revise this stuff, and I couldn&amp;rsquo;t just go into a treatment room and start fiddling with a machine the way I normally would. Could I build the menu system for the machine for myself as a revision aid?&lt;/p&gt;
&lt;h2 id=&#34;app-is-a-bit-of-a-grand-term&#34;&gt;&amp;lsquo;App&amp;rsquo; is a bit of a grand term&lt;/h2&gt;
&lt;p&gt;Having played with adapting someone else&amp;rsquo;s JavaScript for the &lt;a href=&#34;https://jmablog.com/post/posenet-app&#34;&gt;PoseNet app&lt;/a&gt; I built for my business module assessment, I was starting to get a grip on how JavaScript can be used to build interactivity into a website (in very basic terms). I didn&amp;rsquo;t have a lot of time to learn something advanced for web app development (&lt;a href=&#34;https://localghost.dev&#34;&gt;my wife&lt;/a&gt; is a software engineer and I&amp;rsquo;ve often looked over her shoulder at the React based things she&amp;rsquo;s building and felt like she was essentially performing arcane rituals to tame futuristic cyber gods). What did I know already that could get this job done?&lt;/p&gt;
&lt;p&gt;I present: an electrotherapy &amp;lsquo;machine&amp;rsquo; built entirely out of showing and hiding CSS modal boxes when the user clicks various buttons.&lt;/p&gt;


&lt;video width=&#34;100%&#34; loop controls class=&#34;ba bw1 mv3&#34;&gt;
  &lt;source src=&#34;app-demo.mp4&#34; type=&#34;video/mp4&#34;&gt;
  &lt;em&gt;Sorry, your browser does not support the video tag.&lt;/em&gt;
&lt;/video&gt;

&lt;p&gt;You can view the code &lt;a href=&#34;https://github.com/jmablog/jmablog-code-snippets/tree/master/electrotherapy-app&#34;&gt;here&lt;/a&gt;. It&amp;rsquo;s nothing special; I was getting better but was still rusty with my basic HTML/CSS, and JavaScript was still a new foreign land I was exploring. But it got the job done.&lt;/p&gt;
&lt;p&gt;The hardest part was actually figuring out what the menu options should be. I&amp;rsquo;d had a go on the electrotherapy machines at uni, but not enough to memorise every part of their menu layout. There were revision videos on our student portal, but the video quality was so low that I couldn&amp;rsquo;t make out any of the text on the machine screens. I had to learn the parameters for electrotherapy treatment really well, and then use educated guesses to determine what they are &lt;em&gt;probably&lt;/em&gt; selecting at each point in the video based on the treatment they were demonstrating, in order to figure out what menu item should occur in what order on the screen. I also found the PDF manual online for the specific model of electrotherapy machine we use, but even that left gaps I had to fill in with detective work.&lt;/p&gt;
&lt;p&gt;All this turned out to be &lt;em&gt;fantastic&lt;/em&gt; revision. Building a thing really is the best way to learn how that thing works! As a result, by the time I felt happy with the finished product, I didn&amp;rsquo;t even need to use it anymore.&lt;/p&gt;
&lt;p&gt;And then I thought - could an emulation like this stand in for the real thing in the exam? Screensharing could allow a student to select variables in the app while the examiner watched, exactly as they would when standing in front of a physical machine. Would the university accept that? Feeling bold, I emailed it off to my lecturer.&lt;/p&gt;
&lt;p&gt;About a month later, it was used in the electrotherapy assessment for everyone on my course.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m very proud of this small part I played in helping life carry on during an incredibly turbulent, Covid-19 flavoured time. &lt;em&gt;And&lt;/em&gt; I&amp;rsquo;m pretty sure I&amp;rsquo;ve build the only online emulation of an electrotherapy machine menu that exists on the internet (&lt;a href=&#34;https://twitter.com/jmablog&#34;&gt;let me know&lt;/a&gt; if I&amp;rsquo;m wrong please). Talk about niche. It&amp;rsquo;s still there, on Github, incidentally. If you&amp;rsquo;re a sports therapy student looking for a revision aid for electrotherapy, you can &lt;a href=&#34;https://jmablog.github.io/jmablog-code-snippets/electrotherapy-app/&#34;&gt;try it for yourself by clicking here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Hope it helps.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>SquatCam: Real-time Joint Feedback with PoseNet</title>
            <link>https://jmablog.com/post/posenet-app/</link>
            <pubDate>Sat, 25 Jul 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/posenet-app/</guid>
            <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update:&lt;/strong&gt; Since first writing this post, I&amp;rsquo;ve actually &lt;a href=&#34;https://squatcam.vercel.app/&#34;&gt;updated the web app in question&lt;/a&gt; to look a little nicer and even work on smaller screens, so the video demo in this post won&amp;rsquo;t match what you&amp;rsquo;ll see if you &lt;a href=&#34;https://squatcam.vercel.app/&#34;&gt;follow the links to try it yourself&lt;/a&gt;. The basic code running everything remains the same though.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So a while ago, I stumbled onto &lt;a href=&#34;https://blog.tensorflow.org/2018/05/real-time-human-pose-estimation-in.html?m=1&#34;&gt;this post on the TensorFlow blog&lt;/a&gt;, talking about the release of a JavaScript version of the PoseNet machine learning model for real time human pose estimation that can run in a browser using a webcam. I noted it at the time as we were learning about motion capture in Biomechanics during my undergrad Sports Therapy course, and I was curious if this could be used as a form of markerless motion tracking, so I stored it away in the back of my mind.&lt;/p&gt;
&lt;p&gt;Somewhat later, in third year, we had to take a Business Studies module. The one and only assessment for this module involved creating a business pitch for a new business of our choosing, but ideally related to our field of study. We were encouraged by our lecturer to add some &amp;lsquo;wow factor&amp;rsquo; to the pitch by including something like a video or, even better, a live demonstration of our product.&lt;/p&gt;
&lt;p&gt;The idea struck me to go back to PoseNet and create a business around delivering in-browser biomechanical analysis of movements, that sports therapists could use to assess patients remotely. All the patient would need to do is point their webcam at themselves while moving and the therapist could get a report on joint or segment angles to assess ranges of motion! I knew if I could get a demo of this working the way I wanted, it would definitely provide that &amp;lsquo;wow&amp;rsquo; my lecturer was after.&lt;/p&gt;
&lt;p&gt;One small problem - I&amp;rsquo;d never really done anything in JavaScript, never mind with machine learning. Hell, at that point I was still rusty with my HTML/CSS alone, having not done anything web related for half my life.&lt;/p&gt;
&lt;p&gt;Fortunately for me, I&amp;rsquo;d also recently stumbled on to the &lt;a href=&#34;https://www.youtube.com/user/shiffman&#34;&gt;Coding Train&lt;/a&gt; YouTube channel (seriously, the amount of stumbling onto exactly the thing I need on the web is kind of bizarre). Coding Train had recently uploaded some videos on &amp;lsquo;friendly&amp;rsquo; machine learning models using something called &lt;a href=&#34;https://ml5js.org/&#34;&gt;ml5&lt;/a&gt;, including &lt;a href=&#34;https://www.youtube.com/watch?v=OIo-DIOkNVg&#34;&gt;this one on Posenet&lt;/a&gt; that gave me exactly the base I needed to start. In fact, the &lt;a href=&#34;https://learn.ml5js.org/docs/#/reference/posenet?id=examples&#34;&gt;example code for PoseNet with a webcam using ml5.js and p5.js&lt;/a&gt; is nearly entirely intact in my final code - I just built a couple things on top of it. I can heartily recommend both Coding Train and ml5 for anyone looking to start playing with some really interesting machine learning models!&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t have time to build much, so I focused on one movement - the squat - and built a simple single page app that takes the pose info from PoseNet and adds a couple extra bits of maths to present some common biomechanical markers, before logging them to a little dashboard. Here&amp;rsquo;s an example video:&lt;/p&gt;


&lt;video width=&#34;100%&#34; loop controls class=&#34;ba bw1 mv3&#34;&gt;
  &lt;source src=&#34;demo.mp4&#34; type=&#34;video/mp4&#34;&gt;
  &lt;em&gt;Sorry, your browser does not support the video tag.&lt;/em&gt;
&lt;/video&gt;

&lt;p&gt;Please excuse my general shabby state in the video - I was in full Covid-19 lockdown mode at the point this was recorded.&lt;/p&gt;
&lt;p&gt;The PoseNet and skeleton-drawing (the white lines and dots overlaying the video) code was already there from ml5, so now I had to figure out how to get the joint and segment angles. I had the &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; coordinates of each white dot representing a joint, so I figured there must be a way to translate this into angles.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m no great mathematician, so a little google-fu found me &lt;a href=&#34;https://stackoverflow.com/a/31334882&#34;&gt;this StackOverflow answer&lt;/a&gt; that gave me what I needed. I&amp;rsquo;d used &lt;code&gt;atan2&lt;/code&gt; in R for calculating resultant forces when I was &lt;a href=&#34;https://jmablog.com/post/resultant-forces&#34;&gt;resultant forces&lt;/a&gt;, so I was familiar with how it worked, and a little extra calculation allows you to translate the points in such a way that the &amp;lsquo;joint&amp;rsquo; in our case becomes the equivalent of &lt;code&gt;0, 0&lt;/code&gt; in a coordinate system. Here&amp;rsquo;s an example of this applied to knee flexion, where &lt;code&gt;poses[0]...&lt;/code&gt; is the data coming from PoseNet:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;knee = poses[0].pose.leftKnee;
hip = poses[0].pose.leftHip;
ankle = poses[0].pose.leftAnkle;

kneeFlexion = (
  Math.atan2(
    ankle.y - knee.y,
    ankle.x - knee.x
  )
  - Math.atan2(
    hip.y - knee.y,
    hip.x - knee.x
  )
) * (180 / Math.PI);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;One interesting conundrum was calculating shin and trunk angle, given that these needed to be calculated from a fixed external point (an absolute angle in biomechanics terms) - ideally the floor or a wall. And, I still needed those three points to work with &lt;code&gt;atan2&lt;/code&gt; as in the example above. I ended up creating an imaginary third point, using a combination of the &lt;code&gt;x&lt;/code&gt; coordinate from the most superior joint (shoulder for trunk, knee for shin) and the &lt;code&gt;y&lt;/code&gt; coordinate from the inferior joint (hip, ankle) to project a third point out into space that moved along with these joints and created a nice right angle triangle. I could then, essentially, use the sides of this triangle as the external reference for these angles.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example illustration for trunk lean:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;trunklean.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;And the code:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hip = poses[0].pose.leftHip;
shoulder = poses[0].pose.leftShoulder;
imaginaryPoint = { x: shoulder.x, y: hip.y };

trunkLean = 360 - (
  Math.atan2(
    imaginaryPoint.y - hip.y,
    imaginaryPoint.x - hip.x
  ) - Math.atan2(
    shoulder.y - hip.y,
    shoulder.x - hip.x)
) * (180 / Math.PI);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It&amp;rsquo;s not a perfect system, but it&amp;rsquo;s acceptable enough!&lt;/p&gt;
&lt;p&gt;From there, it was just a case of logging the number reached to a variable and outputting that to the HTML, updating it only if that variable is exceeded - logging the maximum knee flexion achieved, for example. Just to be fancy, I threw in a button to switch sides (which just means changing &lt;code&gt;poses[0].pose.leftKnee&lt;/code&gt; to &lt;code&gt;poses[0].pose.rightKnee&lt;/code&gt;) and a button to snapshot the current video output and download it (using &lt;a href=&#34;https://p5js.org/reference/#/p5/saveCanvas&#34;&gt;p5 saveCanvas&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;For a first time adventure in JavaScript, this was probably jumping in at the deep end, but I&amp;rsquo;m pleased with the outcome (and it must have achieved that wow factor I was after, as I got a pretty great mark on the assessment). You can view the (probably quite ugly) &lt;a href=&#34;https://github.com/jmablog/squatcam&#34;&gt;code on GitHub&lt;/a&gt; and even &lt;a href=&#34;https://squatcam.vercel.app/&#34;&gt;try it for yourself here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once again, check out &lt;a href=&#34;https://ml5js.org/&#34;&gt;ml5&lt;/a&gt; and &lt;a href=&#34;https://www.youtube.com/user/shiffman&#34;&gt;Coding Train&lt;/a&gt; for more machine learning model goodness!&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Common parkour vault techniques, landing styles, and their effects on landing forces</title>
            <link>https://jmablog.com/research/pkvs/</link>
            <pubDate>Thu, 16 Jul 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/research/pkvs/</guid>
            <description>&lt;p&gt;This project was my final year dissertation for my Sport Therapy BSc undergraduate degree, the abstract of which was accepted at the &lt;a href=&#34;https://www.bases.org.uk&#34;&gt;BASES Conference 2021&lt;/a&gt; and presented as a poster where it won the &lt;a href=&#34;https://www.bases.org.uk/sspage-awards___grants-awards-conference_awards_hall_of_fame.html&#34;&gt;Human Kinetics Student Poster Presentation Award&lt;/a&gt;. This abstract was then also published in a &lt;a href=&#34;https://www.tandfonline.com/doi/full/10.1080/02640414.2021.1978748&#34;&gt;special edition of the Journal of Sports Sciences&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;read-online&#34;&gt;Read Online&lt;/h2&gt;
&lt;p&gt;&amp;#x1f4d4; &lt;a href=&#34;read/&#34;&gt;Read online in full&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;#x1f4c4; &lt;a href=&#34;https://www.researchgate.net/publication/342978645_Common_parkour_vaulting_techniques_landing_styles_and_their_effects_on_landing_forces&#34;&gt;Download PDF&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;bonus-materials&#34;&gt;Bonus Materials&lt;/h2&gt;
&lt;p&gt;🗒 &lt;a href=&#34;https://www.tandfonline.com/doi/full/10.1080/02640414.2021.1978748&#34;&gt;Abstract in the Journal of Sports Sciences&lt;/a&gt; &lt;em&gt;(search for the reference code D2.S3 on that page to find it!)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;🗞 &lt;a href=&#34;https://www.researchgate.net/publication/343135659_Common_parkour_vaulting_techniques_landing_styles_and_their_effects_on_landing_forces&#34;&gt;BASES 2021 Conference Poster&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;#x26a1; &lt;a href=&#34;slides/&#34;&gt;View summary slides&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;It’s important to know that this has &lt;strong&gt;not&lt;/strong&gt; been extensively peer reviewed beyond the abstract for the BASES Conference. I’m proud of my work and I think my findings are, at the very least, interesting. But, please bear that in mind as you read it.&lt;/p&gt;
&lt;h2 id=&#34;data&#34;&gt;Data&lt;/h2&gt;
&lt;p&gt;You can also download the full force platform data I collected if you would like to perform your own analysis. If you do so, please get in touch and let me know what you use it for and what you find, I&amp;rsquo;d be delighted.&lt;/p&gt;
&lt;p&gt;⬇ &lt;a href=&#34;https://doi.org/10.6084/m9.figshare.12231089&#34;&gt;Download from Figshare&lt;/a&gt; |  ⬇ &lt;a href=&#34;https://github.com/jmablog/common-parkour-vault-techniques&#34;&gt;Download from Github repo&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;abstract&#34;&gt;Abstract&lt;/h2&gt;
&lt;p&gt;The emerging sport of parkour has developed a landing technique focused on soft, quiet and controlled landings. The proficiency of practitioners (traceurs) for two-legged drop landing tasks is becoming increasingly established, but it is unknown whether the same aptitude will be demonstrated for different movements and with different landing techniques. This study will investigate the ground reaction forces (GRFs) produced during three common parkour vaulting techniques utilising two common landing styles, with the aim of understanding how GRFs may change between the different scenarios and the subsequent implications for injury risk. 10 traceurs (age 29.4 ± 7.2 years, height 173.8 ± 8.1 cm, weight 74.2 ± 8.4 kg, experience 9.7 ± 3.6 years) performed a drop landing, step vault, dash vault, and kong vault onto a force plate with a two-legged precision landing (precision) and a single-legged running landing (running). Peak vertical (vGRF) and braking (bGRF) GRFs per limb were analysed by repeated-measures two-way ANOVA. A significant interaction effect between movement choice and landing style was found for both peak vGRF (&lt;em&gt;p&lt;/em&gt; = 0.007) and peak bGRF (&lt;em&gt;p&lt;/em&gt; &amp;lt; 0.001). All movements increased in vGRF when using a running landing, but only the drop and kong vault increased in bGRF while the step and dash vaults decreased in bGRF. The kong vault resulted in the greatest peak vGRFs and bGRFs, differing significantly from all other movements with a precision landing and, even in comparisons that did not achieve significance, always producing at least a medium to large effect size. The dash vault produced the least peak vGRF and bGRF of all movements in both landing styles, differing significantly from all others in bGRF and the drop and kong vault in vGRF. Movement and landing style choice affect landing GRFs for common parkour vaulting techniques. While GRFs increased in running style landings, they still did not exceed those typically experienced in jogging, indicating that traceurs mimic their performance in two-legged drop landings and continue to effectively mitigate GRFs when vaulting. As a result traceurs are unlikely to be at risk of acute lower limb injury when vaulting, but may remain at risk of chronic lower limb injury.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;read/&#34;&gt;Continue reading&amp;hellip;&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Astronaut Mission Length: Longest v Average</title>
            <link>https://jmablog.com/post/astronaut-mission-length-longest-v-average/</link>
            <pubDate>Tue, 14 Jul 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/astronaut-mission-length-longest-v-average/</guid>
            <description>&lt;p&gt;&lt;em&gt;(&lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;Tidy Tuesday&lt;/a&gt; is a project to supply weekly data sets for R users to practice their coding skills on. You can find &lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;full details here&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/rfordatascience/tidytuesday/blob/master/data/2020/2020-07-14/readme.md&#34;&gt;This week&amp;rsquo;s&lt;/a&gt; Tidy Tuesday dataset &amp;ldquo;contains publicly available information about all astronauts who participated in space missions before 15 January 2020 collected from NASA, Roscosmos, and fun-made websites.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Without a clear immediate question jumping out at me, I played around with the dataset a bunch to see what random variables I could make it spit out. I ended up with an average mission length for astronauts that flew more than one mission. Since I hadn&amp;rsquo;t really had a chance to play with creating a &lt;a href=&#34;https://datavizproject.com/data-type/dumbbell-plot/&#34;&gt;dumbbell plot&lt;/a&gt; before, I gave it a go.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;plot.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;It came out quite nicely as a visual, but the thing I really love about this plot is how utterly &lt;em&gt;useless&lt;/em&gt; this information really is. I mean, it answers the question, but so what? I can&amp;rsquo;t think of a situation where knowing this going to be particularly useful in solving a problem. Perfect!&lt;/p&gt;
&lt;p&gt;I used &lt;code&gt;reorder_within&lt;/code&gt; from &lt;a href=&#34;https://github.com/juliasilge/tidytext&#34;&gt;tidytext&lt;/a&gt; to order the astronaut names by longest mission within each facet of mission number. It&amp;rsquo;s one of the most useful functions for plotting I know, kinda hidden away in a package that I never use anything else from. I did hit a small glitch where you need to also use &lt;code&gt;reorder_within&lt;/code&gt; on &lt;code&gt;xend&lt;/code&gt; in &lt;code&gt;geom_segment&lt;/code&gt; for the lines of the dumbbells to line up properly. That took a minute to figure out.&lt;/p&gt;
&lt;p&gt;Also a fun bit of use of &lt;a href=&#34;https://github.com/wilkelab/ggtext&#34;&gt;ggtext&lt;/a&gt; to put colour into the plot title, as it was much easier than trying to figure out how to put in a legend for the dumbbell ends. And a shout out to &lt;a href=&#34;https://regex101.com/&#34;&gt;Regex101&lt;/a&gt; for helping me put together the &lt;code&gt;str_replace_all&lt;/code&gt; to abbreviate all the astronaut names.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;library(tidyverse)
library(tidytuesdayR)
library(here)
library(tidytext)
library(ggthemr)
library(cowplot)
library(ggtext)
library(glue)

ggthemr(&amp;#34;flat dark&amp;#34;, type = &amp;#34;outer&amp;#34;)

data &amp;lt;- tt_load(2020, week=29)$astronauts

avgs &amp;lt;- data %&amp;gt;%
  group_by(name) %&amp;gt;%
  summarise(across(hours_mission, mean, .names = &amp;#34;mean_{col}&amp;#34;),
            longest_mission = round(max(hours_mission)/24, 2),
            no_mission = unique(total_number_of_missions),
            total_hrs = unique(total_hrs_sum)) %&amp;gt;%
  mutate(avg_days_per_mission = round(mean_hours_mission / 24, 2),
         total_days = round(total_hrs / 24, 2)) %&amp;gt;%
  arrange(desc(avg_days_per_mission)) %&amp;gt;%
  select(-mean_hours_mission, -total_hrs) %&amp;gt;%
  filter(no_mission &amp;gt; 1) %&amp;gt;%
  group_by(no_mission) %&amp;gt;%
  slice_max(longest_mission, n=10) %&amp;gt;%
  ungroup()
  
plot &amp;lt;- avgs %&amp;gt;%
  mutate(no_mission = glue::glue(&amp;#34;{no_mission} Missions&amp;#34;),
         name = str_replace_all(name,
                                &amp;#34;(\\w+), (.)[a-zA-Z]+($|( .).($|(, Jr)))&amp;#34;,
                                &amp;#34;\\1, \\2.\\3&amp;#34;),
         name = str_replace(name,
                            &amp;#34;Yuri Vladimirovich Usachyov&amp;#34;,
                            &amp;#34;Yuri, V. U.&amp;#34;)) %&amp;gt;%
  ggplot(aes(x = reorder_within(name,
                                longest_mission,
                                no_mission))) +
  geom_segment(aes(xend = reorder_within(name,
                                         longest_mission,
                                         no_mission),
                   y = avg_days_per_mission,
                   yend = longest_mission),
               color = &amp;#34;white&amp;#34;) +
  geom_point(aes(y = longest_mission),
             color = swatch()[4],
             size = 2) +
  geom_point(aes(y = avg_days_per_mission),
             color = swatch()[3],
             size = 2) +
  scale_x_reordered() +
  coord_flip() +
  facet_wrap(vars(no_mission), ncol = 2, scales = &amp;#34;free_y&amp;#34;) +
  labs(x = &amp;#34;&amp;#34;,
       y = &amp;#34;Mission Length (Days)&amp;#34;,
       title = glue(&amp;#34;How much longer than &amp;lt;span style=&amp;#39;color:{swatch()[3]};&amp;#39;&amp;gt;average&amp;lt;/span&amp;gt; was their &amp;lt;span style=&amp;#39;color:{swatch()[4]};&amp;#39;&amp;gt;longest&amp;lt;/span&amp;gt; mission?&amp;#34;),
       subtitle = &amp;#34;For the 10 longest missions by astronauts that flew more than one mission&amp;#34;) + 
  theme(plot.title.position = &amp;#34;plot&amp;#34;,
        plot.title = element_markdown(),
        strip.text = element_text(face = &amp;#34;bold&amp;#34;),
        axis.title.x = element_text(face = &amp;#34;bold&amp;#34;))
        
ggdraw(plot) +
  draw_image(here(&amp;#34;astronauts&amp;#34;, &amp;#34;rocket.png&amp;#34;),
             scale = 0.06, x = .25, y = .45)
&lt;/code&gt;&lt;/pre&gt;</description>
        </item>
        
        <item>
            <title>Which X-Men character had it worst?</title>
            <link>https://jmablog.com/post/which-x-men-character-had-it-worst/</link>
            <pubDate>Wed, 08 Jul 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/which-x-men-character-had-it-worst/</guid>
            <description>&lt;p&gt;&lt;em&gt;(&lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;Tidy Tuesday&lt;/a&gt; is a project to supply weekly data sets for R users to practice their coding skills on. You can find &lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;full details here&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A little late, but I decided to have a go at Tidy Tuesday with the recent &lt;a href=&#34;https://github.com/rfordatascience/tidytuesday/blob/master/data/2020/2020-06-30/readme.md&#34;&gt;Claremont Run&lt;/a&gt; dataset, looking at Chris Claremont&amp;rsquo;s 16 year run writing for the Uncanny X-men comic.&lt;/p&gt;
&lt;p&gt;Looking at the &lt;code&gt;characters&lt;/code&gt; dataset provided, that describe some of the events that occur to each character in an issue, it seemed like being an X-Person was a pretty rough gig. I wondered, who got dealt the harshest hand during the entire Claremont run?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;xmen-plot.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Poor Storm.&lt;/p&gt;
&lt;p&gt;This also gave me a chance to (very slightly) play with the new &lt;code&gt;across&lt;/code&gt; (&lt;a href=&#34;https://dplyr.tidyverse.org/reference/across.html&#34;&gt;docs&lt;/a&gt;) function in the latest &lt;a href=&#34;https://dplyr.tidyverse.org&#34;&gt;dplyr&lt;/a&gt; release. I&amp;rsquo;ve seen a few blog posts from excited R users around singing it&amp;rsquo;s praises, so it was good to at least touch it, even if I clearly haven&amp;rsquo;t made the most of it here.&lt;/p&gt;
&lt;p&gt;I also played with &lt;code&gt;adorn_totals&lt;/code&gt; from the &lt;a href=&#34;https://github.com/sfirke/janitor&#34;&gt;Janitor&lt;/a&gt; package for the first time, as well as adding an image to a plot with &lt;a href=&#34;https://wilkelab.org/cowplot/index.html&#34;&gt;Cowplot&amp;rsquo;s&lt;/a&gt; &lt;code&gt;draw_image&lt;/code&gt;. Random new functions - always my favourite thing about working with R.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;yall.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;library(tidyverse)
library(janitor)
library(tidytuesdayR)
library(ggthemr)
library(cowplot)
library(here)

# set theme with ggthemr
ggthemr(&amp;#39;fresh&amp;#39;)

# import tidy tuesday data
data &amp;lt;- tt_load(2020, week=27)
characters &amp;lt;- data$characters

# summarise total instances the state occurred on each character across run
char_states_totals &amp;lt;- characters %&amp;gt;%
  select(-issue) %&amp;gt;%
  group_by(character) %&amp;gt;%
  summarise(across(is.numeric, sum)) %&amp;gt;%
  ungroup() %&amp;gt;%
  select(1:4, 6, 8) %&amp;gt;%
  janitor::adorn_totals(&amp;#34;col&amp;#34;, name = &amp;#34;total&amp;#34;) %&amp;gt;%
  janitor::untabyl() %&amp;gt;%
  slice_max(total, n = 10) %&amp;gt;%
  select(character, total, everything()) %&amp;gt;%
  pivot_longer(3:7, names_to=&amp;#34;state&amp;#34;, values_to = &amp;#34;count&amp;#34;) %&amp;gt;%
  separate(character, sep = &amp;#34; = &amp;#34;, into = c(&amp;#34;codename&amp;#34;, &amp;#34;name&amp;#34;)) %&amp;gt;%
  mutate(codename = case_when(codename == &amp;#34;Ariel/Sprite/Shadowcat&amp;#34; ~ &amp;#34;Shadowcat&amp;#34;,
                              codename == &amp;#34;Marvel Girl/Phoenix&amp;#34; ~ &amp;#34;Jean Grey&amp;#34;,
                              TRUE ~ codename))

# create stacked column plot
plot &amp;lt;- char_states_totals %&amp;gt;%
  mutate(state = str_replace_all(state, &amp;#34;_&amp;#34;, &amp;#34; &amp;#34;),
         state = str_replace_all(state, &amp;#34;subject&amp;#34;, &amp;#34;subjected&amp;#34;),
         state = str_to_sentence(state)) %&amp;gt;%
  mutate(state = fct_reorder(state, count),
         codename = fct_reorder(codename, total)) %&amp;gt;%
  ggplot(aes(codename, count, fill = state)) +
  geom_col() + 
  coord_flip() +
  labs(title = &amp;#34;Which X-Men character had it worst?&amp;#34;,
       subtitle = &amp;#34;During Chris Claremont&amp;#39;s 1975-1991 run on Uncanny X-Men&amp;#34;,
       x = &amp;#34;&amp;#34;,
       y = &amp;#34;No. of Occurrences&amp;#34;,
       fill = &amp;#34;&amp;#34;)

# add storm image to plot
cowplot::ggdraw(plot) +
  cowplot::draw_image(here(&amp;#34;xmen&amp;#34;, &amp;#34;storm.jpg&amp;#34;), scale = .3, x = .37, y = .3) 
&lt;/code&gt;&lt;/pre&gt;</description>
        </item>
        
        <item>
            <title>Differences In Postural Trunk Lean When Implementing A Decline Squat Protocol</title>
            <link>https://jmablog.com/research/differences-in-postural-trunk-lean-when-implementing-a-decline-squat-protocol/</link>
            <pubDate>Wed, 15 Apr 2020 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/research/differences-in-postural-trunk-lean-when-implementing-a-decline-squat-protocol/</guid>
            <description>&lt;p&gt;This research was done as part of our final year biomechanics module. We explored the hypothesis that squatting on a 20° angle decline ramp will result in a more upright trunk at the bottom of the squat, potentially reducing the risk of lumbar spine injury during squatting when ankle dorsiflexion range is limited.&lt;/p&gt;
&lt;p&gt;The abstract for this research was selected for poster presentation at the &lt;a href=&#34;https://www.bases.org.uk&#34;&gt;BASES Student Conference 2020&lt;/a&gt;, but unfortunately due to Covid-19 the conference was cancelled, so my colleagues and I decided to present it online.&lt;/p&gt;
&lt;h2 id=&#34;view-online&#34;&gt;View Online&lt;/h2&gt;
&lt;p&gt;🗞 &lt;a href=&#34;http://dx.doi.org/10.13140/RG.2.2.21413.52963&#34;&gt;Student Conference Poster&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Meteorite Falls and Finds in the UK</title>
            <link>https://jmablog.com/post/meteorite-falls-and-finds-in-the-uk/</link>
            <pubDate>Mon, 17 Jun 2019 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/meteorite-falls-and-finds-in-the-uk/</guid>
            <description>&lt;p&gt;&lt;em&gt;(&lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;Tidy Tuesday&lt;/a&gt; is a project to supply weekly data sets for R users to practice their coding skills on. You can find &lt;a href=&#34;https://github.com/rfordatascience/tidytuesday&#34;&gt;full details here&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The Tidy Tuesday dataset for this week, compiling &lt;a href=&#34;https://github.com/rfordatascience/tidytuesday/blob/master/data/2019/2019-06-11/readme.md&#34;&gt;meteorite strikes across the world&lt;/a&gt;, grabbed my interest so I decided to finally dive in and give it a go. I ended up looking at strikes in the UK, noted by mass.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;meteorite-strikes.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;I exported the original code image as a PDF and then applied some effects in Affinity Photo to give it an old, weathered look. This was my first time experimenting with something like this, so it&amp;rsquo;s a little sketchy, but I enjoyed seeing how I could pull a plot apart in Photo to apply image effects (although sorry, this does mean the code for this plot doesn&amp;rsquo;t get you all the way to the finished produced).&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;library(tidyverse)
library(maps)

meteorites &amp;lt;- readr::read_csv(&amp;#34;https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-06-11/meteorites.csv&amp;#34;)

ukFalls &amp;lt;- meteorites %&amp;gt;% 
  filter(lat &amp;gt;= 50 &amp;amp; lat &amp;lt;= 60 &amp;amp; long &amp;lt;= 2 &amp;amp; long &amp;gt;= -11) %&amp;gt;% 
  filter(!name %in% c(&amp;#34;Limerick&amp;#34;, &amp;#34;Dundrum&amp;#34;, &amp;#34;Mooresfort&amp;#34;, &amp;#34;Leighlinbridge&amp;#34;, &amp;#34;Pettiswood&amp;#34;)) %&amp;gt;%
  mutate(massKG = mass/1000) %&amp;gt;% 
  mutate(nameYear = paste(name, year, sep = &amp;#34;, &amp;#34;)) %&amp;gt;% 
  arrange(year)

ukMap &amp;lt;- map_data(regions = &amp;#34;uk&amp;#34;, map = &amp;#34;world&amp;#34;) %&amp;gt;% filter(lat &amp;lt;=58.73)

ggplot(ukMap, aes(x = long, y = lat)) + 
  geom_polygon(aes(group = group), colour = &amp;#34;black&amp;#34;, fill = &amp;#34;#222831&amp;#34;) +
  geom_point(data = ukFalls, aes(x = long, y = lat, size = massKG), colour = &amp;#34;#d65a31&amp;#34;) +
  geom_text(data = subset(ukFalls, massKG &amp;gt;=10), aes(label = nameYear), hjust = 0, nudge_x = 0.2, size = 3) +
  scale_size(range = c(0, 5), breaks = c(5,15,25,50), labels = c(&amp;#34;5 kg&amp;#34;, &amp;#34;15 kg&amp;#34;, &amp;#34;25 kg&amp;#34;, &amp;#34;50 kg&amp;#34;)) +
  theme_void() +
  theme(plot.background = element_rect(fill = &amp;#34;#5588a3&amp;#34;),
        plot.margin = margin(.5, .5, .5, .5, &amp;#34;cm&amp;#34;)) +
  labs(size = &amp;#34;Mass&amp;#34;,
       alpha = &amp;#34;Mass&amp;#34;)

ggsave(&amp;#34;map.pdf&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;</description>
        </item>
        
        <item>
            <title>Climber&#39;s Brain</title>
            <link>https://jmablog.com/post/climbers-brain/</link>
            <pubDate>Sun, 26 Aug 2018 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/climbers-brain/</guid>
            <description>&lt;p&gt;I&amp;rsquo;ve been enjoying doing some (indoor) climbing recently. It tickles the same problem solving/figuring out a challenge part of my brain that parkour satisfies. I enjoyed this article on the strange brain of Alex Honnold, one of the current greats of climbing:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://nautil.us/issue/61/coordinates/the-strange-brain-of-the-worlds-greatest-solo-climber-rp&#34;&gt;The Strange Brain of the World’s Greatest Solo Climber&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One of the things I found really interesting is the way he seems to have just gotten used to fear through exposure. This is something that, again, I find in common between climbing and parkour. The more you expose yourself to situations that you find scary, the better you are at dealing with them. The fun part is that it spreads to situations that you haven&amp;rsquo;t exactly encountered before, but are just similar enough that your brain can deal with them in the same way. A broad experience of different situations can set you up to deal with fear in many different ways.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>&#39;Find Your Passion&#39; Is Awful Advice</title>
            <link>https://jmablog.com/post/find-your-passion-is-awful-advice/</link>
            <pubDate>Sat, 25 Aug 2018 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/find-your-passion-is-awful-advice/</guid>
            <description>&lt;p&gt;I found this article pretty interesting. The idea of &lt;em&gt;developing&lt;/em&gt; your passion, rather than waiting for it to strike you like a lightning strike, rung very true to me. I didn&amp;rsquo;t take up a sport until I was 22 and never thought I&amp;rsquo;d pursue a career in it until years later. Now I&amp;rsquo;m at university studying it at 31. If I&amp;rsquo;d gone to uni straight from school, I&amp;rsquo;d probably have done something IT related - never in a million years would I have chosen sport therapy.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.theatlantic.com/science/archive/2018/07/find-your-passion-is-terrible-advice/564932/&#34;&gt;Check out the full article here.&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>The Benefits of Using a Half-Kneeling Position</title>
            <link>https://jmablog.com/post/the-benefits-of-using-a-half-kneeling-position/</link>
            <pubDate>Sat, 11 Aug 2018 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/the-benefits-of-using-a-half-kneeling-position/</guid>
            <description>&lt;p&gt;Exploring working from different or weird positions has been something I&amp;rsquo;ve been enjoying lately. I do a lot of my mobility these days from a full kneeling sit position, for example. As such, &lt;a href=&#34;http://www.jtsstrength.com/articles/2015/05/21/3-reasons-why-the-half-kneeling-position-will-improve-your-training/&#34;&gt;I found this article from Juggernaut Strength&lt;/a&gt; to be a great read.&lt;/p&gt;
&lt;p&gt;I switched to split squats a while back over regular squatting because, frankly, I was sick to death of the issues squatting was giving me with my back. Plus, a half kneel/lunge position is the starting point for a lot of explosive movements in sport. I&amp;rsquo;ve definitely seen benefits from the stability challenges to the trunk that the position provides, like the article talks about, and I plan to use it for some overhead work too in the future.&lt;/p&gt;
&lt;p&gt;I think my interest here was inspired by the climbing I&amp;rsquo;ve been doing recently, where you often have to apply strength in unusual angles, but also from a general need to keep switching things up to maintain interest. Keeping the general movement the same - say, an overhead press - but varying it each week with little things like performing from a half-kneel helps avoid monotony. That&amp;rsquo;s the secret if just grinding reps out just doesn&amp;rsquo;t appeal to you!&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Tricking Myself Into Doing Cardio</title>
            <link>https://jmablog.com/post/tricking-myself-into-doing-cardio/</link>
            <pubDate>Sat, 23 Jun 2018 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/tricking-myself-into-doing-cardio/</guid>
            <description>&lt;p&gt;As I&amp;rsquo;ve mentioned before, I&amp;rsquo;m not a huge fan of cardio - I don&amp;rsquo;t really have the attention span for it. I get super bored with long slow distance. I have to find ways to make it interesting, and the best way I&amp;rsquo;ve found is to try and make it about learning some new skill.&lt;/p&gt;
&lt;p&gt;To that end, I&amp;rsquo;ve been trying to learn to skip lately. Skipping is well known as great cardio - there&amp;rsquo;s a reason you see it in all the Rocky movies. I was surprised at how tricky it was to get going at first too, having not done it since my school days, which were longer ago than I care to admit. It also has the added bonus of having some variations and tricks you can throw in to try and learn.&lt;/p&gt;
&lt;p&gt;When working on something like this, I tend not to worry about strict time or rep counts. Instead, I just set a timer for a general amount of time - 10-20 minutes usually - and just work on the skill during that time. I&amp;rsquo;ll still finish with a sweat, but because I&amp;rsquo;m focused more on learning and improving the skill than just counting down the minutes, I don&amp;rsquo;t get bored.&lt;/p&gt;
&lt;p&gt;This video helped me get a bit of the timing down for learning the &amp;lsquo;jogging&amp;rsquo; style skip. I apologise for the dude-bro vibe in the video, but the information is good, and you can check out their entire Youtube channel for more if you&amp;rsquo;re into it.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube-nocookie.com/embed/Sz96SdflS9A?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

</description>
        </item>
        
        <item>
            <title>New Gym Syndrome</title>
            <link>https://jmablog.com/post/new-gym-syndrome/</link>
            <pubDate>Fri, 15 Jun 2018 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/new-gym-syndrome/</guid>
            <description>&lt;p&gt;There’s a &lt;em&gt;unique&lt;/em&gt; type of fear about a new gym. It comes storming up out of your gut and can lay low even the toughest of gym-bros; all stemming from one simple, unknowable fear.&lt;/p&gt;
&lt;p&gt;What if they do something different, that I don’t know about, and I look like an idiot for not knowing it?&lt;/p&gt;
&lt;p&gt;Gyms can be weird places. They can build cultures and subcultures within them that intimidate and exclude just as much as they can elevate and inspire. Cliques and traditions and expectations can all combine into one big melting pot that, if you’re familiar with it, can be as welcoming as your own home. But if you’re &lt;em&gt;not&lt;/em&gt; familiar, they can feel obscure, bording on unfriendly.&lt;/p&gt;
&lt;p&gt;As an example, I recently went to a new gym for the first time and found the single door into the building to be locked. It had one of those keypad things on it, but I couldn’t see anything indicating how I was meant to know the code to get in. I double checked their website; no luck. There weren’t windows so I could wave to someone and look gormless until they took pity on me. Eventually I bit the bullet and just knocked on the door. After a few minutes, a grumpy looking guy who was clearly mid-workout opened it.&lt;/p&gt;
&lt;p&gt;He was silent as I stepped inside and started to head back to his squat rack immediately. Not knowing what was going on, I asked him if I’d used the right door. “Yeah,” he scowled, “and the code for it is right there.”&lt;/p&gt;
&lt;p&gt;The code was &lt;em&gt;inside the gym&lt;/em&gt;. What? Why? How was I supposed to know?!&lt;/p&gt;
&lt;p&gt;Now fortunately I’m an experienced gym-goer and don’t particularly mind making a nuisance of myself. If a complete stranger wants to be grumpy at me, so be it, but I couldn’t help thinking about how this would have all felt if I’d been brand new to training. I know for sure a few years ago I might not have even had the nerve to knock on an imposing door, and if the first person I’d met inside had scowled at me it would have sent me running to the hills. That’s a shame, as getting into training is hard enough without encountering these social or emotional barriers to entry.&lt;/p&gt;
&lt;p&gt;What can you do to avoid this kind of thing? Best thing to do is find a training partner to go with. If they’ve been to the gym before then they guide you, but even if you’re both brand new you’re far less likely to feel awkward if it’s two of you getting something wrong.&lt;/p&gt;
&lt;p&gt;If you can’t find a partner, see if you can book an induction or 1-on-1 session before you get stuck in. Having a staff member show you around really helps - takes notes and don’t be embarrassed to ask hundreds of questions; everything from etiquette to how the lockers work. It’ll come up, trust me, so find out.&lt;/p&gt;
&lt;p&gt;Finally, I’d advise anyone to just hit the ‘screw it’ button occasionally. You’re there to improve yourself and anyone who wants to judge you for minor mistakes is not someone to waste time on. Take it from someone who has fallen arse over head doing handstands in front of an &lt;em&gt;entire&lt;/em&gt; row of packed treadmills &lt;em&gt;more than once&lt;/em&gt;. Laugh it off and try again.&lt;/p&gt;
&lt;p&gt;Eventually you’ll get comfortable in a space and it will become ‘your’ gym. That’s a pretty special feeling and worth persevering for. And hey, when you reach that place and have to open the door for some schmuck who can’t find the code?&lt;/p&gt;
&lt;p&gt;Maybe give them a quick smile on the way in.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Weber&#39;s Law and Weightlifting</title>
            <link>https://jmablog.com/post/webers-law-and-weightlifting/</link>
            <pubDate>Sat, 02 Jun 2018 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/webers-law-and-weightlifting/</guid>
            <description>&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;Short one today, but I found this video really interesting:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube-nocookie.com/embed/hHG8io5qIU8?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;I love a bit of Numberphile and if you remotely enjoyed this one you should check out every other video on the channel.&lt;/p&gt;
&lt;p&gt;Anyway what I found interesting is that you can feel this very principle when weight lifting. It&amp;rsquo;s harder to jump from 10kg to 15kg in an exercise than it is to jump from 100kg to 105kg. It&amp;rsquo;s something intrinsic we kind of just &amp;lsquo;know&amp;rsquo; in the gym, but you can see the theory behind it here.&lt;/p&gt;
&lt;p&gt;Another point to take away from this is that you never entirely know when information is going to apply to your field of interest. Maths and physics may not seem connected to sport and exercise on the surface, but the entire &lt;em&gt;field&lt;/em&gt; of biomechanics is based on it, so keep your eyes open for inspiration everywhere.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Your Burpees Suck</title>
            <link>https://jmablog.com/post/your-burpees-suck/</link>
            <pubDate>Sat, 12 May 2018 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/your-burpees-suck/</guid>
            <description>&lt;p&gt;I’m not sure where this habit of clapping just behind your head while jumping two inches off the ground during a burpee came from, but I hate it. &lt;a href=&#34;https://www.youtube.com/watch?v=YRWA4T1olao&#34;&gt;cough&lt;/a&gt; I’m not saying you’re not still breathing hard by the end, but I suspect it’s just to chase numbers, to be able to do more for the sake of doing more. I like to use burpees as a very explosive full body movement, high speed and high power, and that includes the jump. I don’t necessarily think you &lt;em&gt;should&lt;/em&gt; be able to do a hundred of them in a row.&lt;/p&gt;
&lt;p&gt;Anyway, here’s a video of some better ones, and some other advanced variations. Do them like this. Fewer, harder, in sets. And jump higher.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube-nocookie.com/embed/_xd774h84ao?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;Credit to &lt;a href=&#34;https://juanlugofitness.com&#34;&gt;Juan Lugo Fitness&lt;/a&gt; for the video.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>The Last Conversation You&#39;ll Ever Need To Have About Eating Right</title>
            <link>https://jmablog.com/post/the-last-conversation-youll-ever-need-to-have-about-eating-right/</link>
            <pubDate>Sun, 06 May 2018 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/the-last-conversation-youll-ever-need-to-have-about-eating-right/</guid>
            <description>&lt;p&gt;A great read on the common questions of healthy eating, without faff or any mention of Gwyneth Paltrow. The bit I like is right at the start; honestly, most people already know what is and isn&amp;rsquo;t healthy, but instead we&amp;rsquo;re all looking for shortcuts and super powers. &lt;/p&gt;
&lt;p&gt;Unfortunately I can&amp;rsquo;t remember where it was, but I read about a study that found the most common indicator of &amp;lsquo;healthy&amp;rsquo; eating was whether or not you make your own food. Regular home cooking from whole ingredients led to healthier eating. Essentially the less steps there are between your food going &amp;lsquo;moo&amp;rsquo; in a field and reaching your kitchen, the better.&lt;/p&gt;
&lt;p&gt;Enjoy: &lt;a href=&#34;http://www.grubstreet.com/2018/03/ultimate-conversation-on-healthy-eating-and-nutrition.html&#34;&gt;The Last Conversation You&amp;rsquo;ll Ever Need To Have About Eating Right&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>5 Minutes, Ratios, and Intensity</title>
            <link>https://jmablog.com/post/5-minutes-ratios-and-intensity/</link>
            <pubDate>Sat, 28 Apr 2018 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/5-minutes-ratios-and-intensity/</guid>
            <description>&lt;p&gt;I’ve been struggling a little lately with cardio. I’ve never particularly enjoyed it, but fortunately the sport I do enjoy - parkour - has cardio kind of ‘baked in’. By doing parkour, you’ll work cardio, without really having it be the focus. You won’t be as good as someone who runs, sprints, cycles, etc, as their actual focused training method, but you will at least be able to go up a flight of stairs without throwing up. And hey, I’m not trying to run any marathons, so a basic level of cardio fitness is fine. I want to be able to sprint for a bus when I need to, maybe knock out a slow but steady 5k on occasion, and keep a fairly healthy heart, and that’s about it.&lt;/p&gt;
&lt;p&gt;The trouble has come now that I’m not really doing parkour that much anymore. Not for any particular reason - it’s just been difficult to find a place for it in my life right now. It happens - you move house, start a new job, or in my case, up-end your entire life to start again by going to university at 31. I’ve still been training, but it’s been in the gym at uni, which isn’t exactly bleeding edge in terms of equipment or massively blessed with space, so my training has been in turn limited.&lt;/p&gt;
&lt;p&gt;So I’ve been getting in my calisthenics - levers, muscle ups - and some basic weight lifting. But, well, I’m not a lover of static cardio machines - treadmills, bikes, rowers. And those are kind of my options in this gym. I could go outside and run once I get home, but ideally I want to wrap my training all up in one session so I can get on with my day. And, considering that I don’t enjoy it anyway, having to psyche myself up to train &lt;em&gt;again&lt;/em&gt; at some other time is setting myself up for failure.&lt;/p&gt;
&lt;p&gt;All this is a long way of explaining that I tried the video below and it fucked me right up:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube-nocookie.com/embed/9boaIRTLnns?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;Athlean-X is a great Youtube channel to check out. I think it’s focus is not exactly in line with my own, but I’ve yet to see anything on there that I consider bad information. They’ve got a few of these short, blast-it-out workouts videos. Perfect, I thought. Tack one of these on at the end of a normal gym workout and I’ll get a little cardio hit to just top me up.&lt;/p&gt;
&lt;p&gt;And hey, I’m not really doing anything right now, why not test it out? What’s five minutes going to do?&lt;/p&gt;
&lt;p&gt;Well that was an hour ago and I’m still feeling queasy. That’s not the fault of the video - I went HAM at this, not really taking into account that I had been slacking on cardio lately. But it does go to show how effective such an approach is - you’re only going for five minutes, so make it a hard five minutes. Pick an intensity that works for the workout your doing. A common complaint I hear is not having enough time in a day to train, but that’s only really true if you approach a five minute workout as if it was a half hour workout. Resting between sets for 30 to 60 seconds will render a five minute workout useless, sure - but it’s five minutes! Rest for 5 to 10 seconds instead and you’ll quickly feel the same level of intensity.&lt;/p&gt;
&lt;p&gt;Think of work to rest instead as a ratio. Example - say you set a work:rest ratio of 2:1. You work in some capacity for 2, and rest for 1. So in a 45 minute running session, that’s:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;30 minutes of running&lt;/li&gt;
&lt;li&gt;15 minutes of rest&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That could be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;10 minutes run&lt;/li&gt;
&lt;li&gt;5 minutes rest&lt;/li&gt;
&lt;li&gt;repeated three times&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Five minute is a nice long time to recover in! The exact same ratio of 2:1 in a five minute workout would give you - well, the maths is a bit imprecise (&lt;em&gt;alright, technically, the following is a ratio of 2:0.87, nerds&lt;/em&gt;), but let’s pretend it’s:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3 minutes 30 seconds work&lt;/li&gt;
&lt;li&gt;1 minute 30 seconds rest&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Split it up into three sets again and that’s only 30 seconds of rest at a time - a much higher intensity workout! So, adjust your workout so that intensity scales to your time limit, and you can squeeze a lot more out of a lot less time. As for myself, I&amp;rsquo;ll be repeating the video workout linked above many more times - I&amp;rsquo;ve got buses to catch, after all.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>All The Mobility Exercises You&#39;ll Ever Need</title>
            <link>https://jmablog.com/post/all-the-mobility-exercises-youll-ever-need/</link>
            <pubDate>Fri, 20 Apr 2018 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/all-the-mobility-exercises-youll-ever-need/</guid>
            <description>&lt;p&gt;Mobility is such a big topic, and is kind of in vogue at the moment, so it can be hard to figure out the good from the bad when it comes to exercises and routines to follow. To help, the folks at Hero Academy have put together &lt;a href=&#34;https://www.heromovement.net/blog/mobility-exercises/&#34;&gt;a massive list of 100+ mobility exercises&lt;/a&gt;, organised by body part.&lt;/p&gt;
&lt;p&gt;All you need to do is click the body area you want to work on, and follow the links to find all the details you need from a variety of sources. If you see anything from Tom Merrick (&lt;a href=&#34;http://www.bodyweightwarrior.co.uk/&#34;&gt;Bodyweight Warrior&lt;/a&gt;), I can recommend it!&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re not sure what body part to pick, or if there are too many body parts you want to work on for the time you have, just think about what is causing you the most pain or discomfort right now. Just work on that, until it no longer bothers you, and then pick another area. Eventually you will (hopefully) clear all the troublesome areas and can just mobilise generally as you go. Enjoy!&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>A Day In The Park</title>
            <link>https://jmablog.com/post/a-day-in-the-park/</link>
            <pubDate>Wed, 13 Apr 2016 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/a-day-in-the-park/</guid>
            <description>&lt;p&gt;Sometimes, you just want to get outside, and fall over.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube-nocookie.com/embed/fegKHcHcaqk?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

</description>
        </item>
        
        <item>
            <title>Hanging Out</title>
            <link>https://jmablog.com/post/hanging-out/</link>
            <pubDate>Thu, 31 Mar 2016 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/hanging-out/</guid>
            <description>&lt;p&gt;A day in the gym.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube-nocookie.com/embed/jvQDoyGq65k?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

</description>
        </item>
        
        <item>
            <title>Block</title>
            <link>https://jmablog.com/post/block/</link>
            <pubDate>Sun, 28 Feb 2016 00:00:00 +0000</pubDate>
            <guid>https://jmablog.com/post/block/</guid>
            <description>&lt;p&gt;Sometimes, things worry you for no reason.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube-nocookie.com/embed/NRFeafW60Fc?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

</description>
        </item>
        
    </channel>
</rss>