Author

Zoë Turner

Published

February 14, 2025

Modified

February 14, 2025

Spell checking can be a really important feature of coding, particularly when creating reports, dashboards or websites. Some R solutions have spelling checks built into them, for example RStudio has a spell check function in the IDE (with underlining words that aren’t recognised in the Visual view) and Golem (“a framework for building robust Shiny apps”) has the spelling R package built into it. But when you are creating reports at a fast pace or building dashboards in flexdashboards, Shiny or Quarto, then mistakes may get missed. Spelling, being what it is, can also be incredibly hard to spot: a dropped letter or a switch can be easily overlooked and if you have several files to check you will need a quick and reliable way to do this.

GitHub actions

GitHub actions work, as the name suggests, on GitHub and are stored in the folder .github at the root (the main folder) of the Project. When a Pull Request is made to the main branch, which is good practice, you can trigger actions to flag up issues to resolve before merging.

Whilst it is possible to create GitHub actions using R, Python is a more usual language, particularly in places like the GitHub Marketplace which is where the PySpelling can be found.

The NHS-R Way was one of the first repositories I tried out this GitHub Action and I needed 3 files:

  • .wordlist.txt (in the main folder)
  • .spellcheck.yaml (in the main folder)
  • and in the folder .github/workflows/ the file spellcheck.yml
Hidden files

Files starting with a . may be hidden from view and can be seen in File Explorer by going to View > select Hidden items. However, even doing this may not mean the file shows in the RStudio Files pane.

All the files can be copied without changes but the .wordlist.txt requires specific spellings so you may wish to remove some or all of those used in NHS-R Community in case some of the words added are not suitable for your Project.

Running the GitHub Action to find spellings to save

Adding the three files will undoubtedly fail the GitHub Action when first pushed because it’s likely you will have a spelling that is not recognised by a universal dictionary. Also the checks are case sensitive so if you have any references which change from upper to lower case, these will both need to be listed, like NHS and nhs.

It is possible to expand the GitHub Action page on GitHub to view the log of previously run actions and you will need to do this when it fails. For the spelling GitHub action, each spelling “mistake” is shown between lines of dashes:

--------------------------------------------------------------------------------
NHSRpopulation
--------------------------------------------------------------------------------

I initially searched for the ----- lines using Ctrl+F through the browser but it turns out the search doesn’t extend to the log. I had missed that the log has its own search which appears at the top of the log webpage.

GitHub Action with search towards the right where I had searched multiple dashes

It’s then a manual task going to the wordlist.txt and adding the words and if there are true spelling mistakes it’s possible to search all files in RStudio by using the Ctrl + Shift + F rather than the Ctrl + F to locate the spelling mistake and correct it.

Failed GitHub Actions

Even when a GitHub Action fails the Pull Request can still be accepted.

Sometimes GitHub Actions fail and just need rerunning some time later!

To rerun go to the Actions tab, select the last failed action and in the top right will be a button to select Re-run all jobs or Re-fun failed jobs.

Forcing commits on GitHub

It’s possible to see on the Pull Request that there are multiple force-pushed commits (10 times!). Because there were so many spellings I did this in a few tries, adding a load, pushing the changes and re-running the action. I also was adding them in alphabetical order at first, until I realised I was never going to get through all of these before Christmas (and it’s February!).

On the one hand it’s ok to push all the changes to one commit as they are all related but on the other hand you will see this commit has 121 file changes to it as I had to tidy up a few files (see the later section about a rogue apostrophe). Whilst this was a decision that is ok to make: which is worse, more commits or more file changes, it is never recommended to force push to main or a branch that people are collaborating on because it changes history by changing the commit label. As I was working on a branch and within in Pull Request to main, I’ve reasonably assumed that it’s only me that will be affected by these changes.

The code to force a push is as follows:

  • stage (add) all files (note the dot)
  • amend the previous commit
  • force the push
git add . 
git commit --amend --no-edit
git push -f

Updating a wordlist dictionary with multiple words

The NHS-R Community website had over 900 specific words to add (some were generated from weblinks) and when I (finally) looked for code to speed things up I realised I could just add all the spellings into the list as I found them, import into R to order and remove duplicates. Before importing and sorting just add Header or something similar to the top of the word list as this will become the column name and removed as part of the process.

library(here) # a package which is useful for referring to the project's path
library(dplyr)

file_path <- paste0(here::here(),"/.wordlist.txt")

# Check to see if the file exists (I misspelt this originally as .worldlist so 
# ironically couldn't find the file!)
file.exists(file_path)
[1] TRUE
# Import the .txt file into R as a dataframe
df <- readr::read_delim(file_path, delim = "\t")

# Order and remove duplicates
df2 <- df |> 
  dplyr::arrange(Header) |> 
  unique() 
  
# Write the text file to test.txt, copy over to .wordlist.txt if everything is ok
# or change the file name to .wordlist.txt and overwrite the original 
write.table(df2, "test.txt", 
            sep ="/",
            col.names = FALSE, 
            row.names = FALSE,
            quote = FALSE)

Replacing multiple and non-ascii characters

Copying over the files from WordPress brought across the apostrophe which doesn’t appear to get recognised correctly even when the same is used in the .wordlist so I used the following code from a Gist to find and replace it to ' in multiple files. The only change I made to the Gist was to expand on the list.files base R function to change the pattern to find.qmd files and also show the full path because I was changing files in a subfolder (doing this means that the code to setwd() isn’t necessary):

library(here) # use instead of setwd() to show the file path rather than change it

path_to_subfolder <- paste0(here::here(), "/blog")

list.files(path_to_subfolder, pattern = ".qmd", full.names = TRUE)
  [1] "/__w/nhs-r-community/nhs-r-community/blog/16th-january-newscast.qmd"                                                                                             
  [2] "/__w/nhs-r-community/nhs-r-community/blog/a-dbplyr-based-address-matching-package.qmd"                                                                           
  [3] "/__w/nhs-r-community/nhs-r-community/blog/a-new-kid-on-the-nhs-r-block.qmd"                                                                                      
  [4] "/__w/nhs-r-community/nhs-r-community/blog/a-roundup-from-the-2022-nhs-r-conference-part-1.qmd"                                                                   
  [5] "/__w/nhs-r-community/nhs-r-community/blog/a-roundup-from-the-2022-nhs-r-conference-part-2.qmd"                                                                   
  [6] "/__w/nhs-r-community/nhs-r-community/blog/a-run-chart-is-not-a-run-chart-is-not-a-run-chart.qmd"                                                                 
  [7] "/__w/nhs-r-community/nhs-r-community/blog/a-simple-function-to-create-nice-correlation-plots.qmd"                                                                
  [8] "/__w/nhs-r-community/nhs-r-community/blog/a-simple-function-to-install-and-load-packages-in-r.qmd"                                                               
  [9] "/__w/nhs-r-community/nhs-r-community/blog/a-thank-you-note-to-nhs-r-community.qmd"                                                                               
 [10] "/__w/nhs-r-community/nhs-r-community/blog/aiming-for-a-wrangle-free-or-reduced-world.qmd"                                                                        
 [11] "/__w/nhs-r-community/nhs-r-community/blog/alignment-cheatsheet.qmd"                                                                                              
 [12] "/__w/nhs-r-community/nhs-r-community/blog/animated-population-pyramids-in-r-part-1.qmd"                                                                          
 [13] "/__w/nhs-r-community/nhs-r-community/blog/animating-a-graph-over-time-in-shiny.qmd"                                                                              
 [14] "/__w/nhs-r-community/nhs-r-community/blog/annotating-spc-plots-using-annotate-with-ggplot.qmd"                                                                   
 [15] "/__w/nhs-r-community/nhs-r-community/blog/announcing-a-new-nhs-r-hexitime-partnership.qmd"                                                                       
 [16] "/__w/nhs-r-community/nhs-r-community/blog/apha-april-blog.qmd"                                                                                                   
 [17] "/__w/nhs-r-community/nhs-r-community/blog/apha-blog-august-2023.qmd"                                                                                             
 [18] "/__w/nhs-r-community/nhs-r-community/blog/apha-blog-may-2023.qmd"                                                                                                
 [19] "/__w/nhs-r-community/nhs-r-community/blog/apha-june-blog.qmd"                                                                                                    
 [20] "/__w/nhs-r-community/nhs-r-community/blog/asking_for_help.qmd"                                                                                                   
 [21] "/__w/nhs-r-community/nhs-r-community/blog/building-a-quarto-website.qmd"                                                                                         
 [22] "/__w/nhs-r-community/nhs-r-community/blog/building-the-ons-mortality-dataset.qmd"                                                                                
 [23] "/__w/nhs-r-community/nhs-r-community/blog/but-this-worked-the-last-time-i-ran-it.qmd"                                                                            
 [24] "/__w/nhs-r-community/nhs-r-community/blog/can-we-rely-on-synthetic-data-to-overcome-data-governance-issue-in-healthcare.qmd"                                     
 [25] "/__w/nhs-r-community/nhs-r-community/blog/code-snippets-2-scale-y-axes-in-ggplot2.qmd"                                                                           
 [26] "/__w/nhs-r-community/nhs-r-community/blog/code-snippets-first-last-and-nth-dplyr-functions.qmd"                                                                  
 [27] "/__w/nhs-r-community/nhs-r-community/blog/code-snippets-regular-expressions.qmd"                                                                                 
 [28] "/__w/nhs-r-community/nhs-r-community/blog/coding-to-and-from-NA.qmd"                                                                                             
 [29] "/__w/nhs-r-community/nhs-r-community/blog/coffee-and-code.qmd"                                                                                                   
 [30] "/__w/nhs-r-community/nhs-r-community/blog/count-of-working-days-function.qmd"                                                                                    
 [31] "/__w/nhs-r-community/nhs-r-community/blog/cqc-data.qmd"                                                                                                          
 [32] "/__w/nhs-r-community/nhs-r-community/blog/create-synthetic-data.qmd"                                                                                             
 [33] "/__w/nhs-r-community/nhs-r-community/blog/designing-my-first-shiny-dashboard.qmd"                                                                                
 [34] "/__w/nhs-r-community/nhs-r-community/blog/diverging-bar-charts-plotting-variance-with-ggplot2.qmd"                                                               
 [35] "/__w/nhs-r-community/nhs-r-community/blog/diverging-dot-plot-and-lollipop-charts-plotting-variance-with-ggplot2.qmd"                                             
 [36] "/__w/nhs-r-community/nhs-r-community/blog/dont-repeat-yourself-functions.qmd"                                                                                    
 [37] "/__w/nhs-r-community/nhs-r-community/blog/dygraphs.qmd"                                                                                                          
 [38] "/__w/nhs-r-community/nhs-r-community/blog/even-simpler-sql.qmd"                                                                                                  
 [39] "/__w/nhs-r-community/nhs-r-community/blog/evolution-of-the-r-user.qmd"                                                                                           
 [40] "/__w/nhs-r-community/nhs-r-community/blog/exact-matching-in-r.qmd"                                                                                               
 [41] "/__w/nhs-r-community/nhs-r-community/blog/forecasting-r-virtual-workshop-the-pupils-perspective.qmd"                                                             
 [42] "/__w/nhs-r-community/nhs-r-community/blog/forecasting-r.qmd"                                                                                                     
 [43] "/__w/nhs-r-community/nhs-r-community/blog/format-ons-spreadsheet.qmd"                                                                                            
 [44] "/__w/nhs-r-community/nhs-r-community/blog/from-script-based-development-to-function-based-development-and-onwards-to-package-based-development-part-2.qmd"       
 [45] "/__w/nhs-r-community/nhs-r-community/blog/from-script-based-development-to-function-based-development-and-onwards-to-package-based-development.qmd"              
 [46] "/__w/nhs-r-community/nhs-r-community/blog/fuzzy_joining_tables.qmd"                                                                                              
 [47] "/__w/nhs-r-community/nhs-r-community/blog/github-action-spelling-check.qmd"                                                                                      
 [48] "/__w/nhs-r-community/nhs-r-community/blog/guest-blogger-chatgpt.qmd"                                                                                             
 [49] "/__w/nhs-r-community/nhs-r-community/blog/hexitime-is-shortlisted-as-a-finalist-for-the-hsj-partnership-awards-2021.qmd"                                         
 [50] "/__w/nhs-r-community/nhs-r-community/blog/histogram-with-auto-binning-in-ggplot2.qmd"                                                                            
 [51] "/__w/nhs-r-community/nhs-r-community/blog/how-nhs-r-community-do-the-apprentice.qmd"                                                                             
 [52] "/__w/nhs-r-community/nhs-r-community/blog/how-r-changed-me-as-an-analyst.qmd"                                                                                    
 [53] "/__w/nhs-r-community/nhs-r-community/blog/how-to-extrapolate-data-from-data.qmd"                                                                                 
 [54] "/__w/nhs-r-community/nhs-r-community/blog/importing-and-exporting-data.qmd"                                                                                      
 [55] "/__w/nhs-r-community/nhs-r-community/blog/index.qmd"                                                                                                             
 [56] "/__w/nhs-r-community/nhs-r-community/blog/introduction-to-funnel-plots.qmd"                                                                                      
 [57] "/__w/nhs-r-community/nhs-r-community/blog/join-the-fun-join-nhs-r.qmd"                                                                                           
 [58] "/__w/nhs-r-community/nhs-r-community/blog/july-blog.qmd"                                                                                                         
 [59] "/__w/nhs-r-community/nhs-r-community/blog/learned-from-community.qmd"                                                                                            
 [60] "/__w/nhs-r-community/nhs-r-community/blog/local-public-health-joins-the-party.qmd"                                                                               
 [61] "/__w/nhs-r-community/nhs-r-community/blog/moving-on-with-the-plan.qmd"                                                                                           
 [62] "/__w/nhs-r-community/nhs-r-community/blog/navigating-the-data-driven-frontier-insights-from-an-nhs-r-committee-member.qmd"                                       
 [63] "/__w/nhs-r-community/nhs-r-community/blog/new-year-new-laptop-new-library-location-new-version-of-r.qmd"                                                         
 [64] "/__w/nhs-r-community/nhs-r-community/blog/nhs-low-income-scheme.qmd"                                                                                             
 [65] "/__w/nhs-r-community/nhs-r-community/blog/nhs-meets-r.qmd"                                                                                                       
 [66] "/__w/nhs-r-community/nhs-r-community/blog/nhs-number-validation.qmd"                                                                                             
 [67] "/__w/nhs-r-community/nhs-r-community/blog/nhs-open-source-public-datasets.qmd"                                                                                   
 [68] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-2020-week-long-conference-so-much-great-content-so-little-time-to-catch-it-all.qmd"                              
 [69] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-book-club.qmd"                                                                                                   
 [70] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-community-conference-2023-my-experience-of-the-event.qmd"                                                        
 [71] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-community-conference-ii.qmd"                                                                                     
 [72] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-community-conference-my-experience-of-the-day.qmd"                                                               
 [73] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-community-conference-organisers-perspective.qmd"                                                                 
 [74] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-community-conference-view-from-the-the-chartered-society-of-physiotherapy-csp.qmd"                               
 [75] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-community-datasets-package-released.qmd"                                                                         
 [76] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-community-member-profile.qmd"                                                                                    
 [77] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-community-needs-help.qmd"                                                                                        
 [78] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-conference-was-it-worth-it.qmd"                                                                                  
 [79] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-newscast-15th-august.qmd"                                                                                        
 [80] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-newscast-20th-july-2023.qmd"                                                                                     
 [81] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-newscast-25th-may-2023.qmd"                                                                                      
 [82] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-newscast-28th-october-2022.qmd"                                                                                  
 [83] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-newscast-6th-july-2022.qmd"                                                                                      
 [84] "/__w/nhs-r-community/nhs-r-community/blog/nhs-r-workshop-development-and-validation-of-clinical-prediction-models-using-r.qmd"                                   
 [85] "/__w/nhs-r-community/nhs-r-community/blog/nhsr-rguably-the-best-conference-in-the-world.qmd"                                                                     
 [86] "/__w/nhs-r-community/nhs-r-community/blog/nhsrdatasets-meets-runcharter.qmd"                                                                                     
 [87] "/__w/nhs-r-community/nhs-r-community/blog/optimising-dplyr.qmd"                                                                                                  
 [88] "/__w/nhs-r-community/nhs-r-community/blog/our-first-ever-nhs-r-webinar.qmd"                                                                                      
 [89] "/__w/nhs-r-community/nhs-r-community/blog/pareto-chart-in-ggplot2.qmd"                                                                                           
 [90] "/__w/nhs-r-community/nhs-r-community/blog/phsmethods-an-r-package-for-public-health-scotland.qmd"                                                                
 [91] "/__w/nhs-r-community/nhs-r-community/blog/posit-nhs-r-a-perfect-partnership.qmd"                                                                                 
 [92] "/__w/nhs-r-community/nhs-r-community/blog/publish-on-github.qmd"                                                                                                 
 [93] "/__w/nhs-r-community/nhs-r-community/blog/r-studio-shortcuts.qmd"                                                                                                
 [94] "/__w/nhs-r-community/nhs-r-community/blog/reflections-on-the-nhs-r-community-conference.qmd"                                                                     
 [95] "/__w/nhs-r-community/nhs-r-community/blog/rforhealthcare.qmd"                                                                                                    
 [96] "/__w/nhs-r-community/nhs-r-community/blog/roadmap-to-collaborative-working-using-r-in-the-nhs-part-i-workflows.qmd"                                              
 [97] "/__w/nhs-r-community/nhs-r-community/blog/rstudio-and-git-selecting-many-files.qmd"                                                                              
 [98] "/__w/nhs-r-community/nhs-r-community/blog/showcasing-functions-separate.qmd"                                                                                     
 [99] "/__w/nhs-r-community/nhs-r-community/blog/simpler-sql-with-dplyr.qmd"                                                                                            
[100] "/__w/nhs-r-community/nhs-r-community/blog/software-licensing.qmd"                                                                                                
[101] "/__w/nhs-r-community/nhs-r-community/blog/spc-charting-in-r.qmd"                                                                                                 
[102] "/__w/nhs-r-community/nhs-r-community/blog/sql-server-database-connections-in-r.qmd"                                                                              
[103] "/__w/nhs-r-community/nhs-r-community/blog/success-story-kate-cheema.qmd"                                                                                         
[104] "/__w/nhs-r-community/nhs-r-community/blog/success-story-lydia-briggs.qmd"                                                                                        
[105] "/__w/nhs-r-community/nhs-r-community/blog/success-story-william-bryant.qmd"                                                                                      
[106] "/__w/nhs-r-community/nhs-r-community/blog/text-mining-term-frequency-analysis-and-word-cloud-creation.qmd"                                                       
[107] "/__w/nhs-r-community/nhs-r-community/blog/the-data-science-assembly.qmd"                                                                                         
[108] "/__w/nhs-r-community/nhs-r-community/blog/the-first-ever-train-the-trainer-class-2019.qmd"                                                                       
[109] "/__w/nhs-r-community/nhs-r-community/blog/the-health-service-modelling-associates-hsma-programme-the-future-of-analytics-for-health-social-care-and-policing.qmd"
[110] "/__w/nhs-r-community/nhs-r-community/blog/the-joy-of-r.qmd"                                                                                                      
[111] "/__w/nhs-r-community/nhs-r-community/blog/the-nhs-r-community-and-hexitime-our-1st-month-of-collaborating.qmd"                                                   
[112] "/__w/nhs-r-community/nhs-r-community/blog/the-nhs-r-conference-2019.qmd"                                                                                         
[113] "/__w/nhs-r-community/nhs-r-community/blog/the-nhsnumber-package-and-the-joy-of-sharing-your-niche.qmd"                                                           
[114] "/__w/nhs-r-community/nhs-r-community/blog/the-operator.qmd"                                                                                                      
[115] "/__w/nhs-r-community/nhs-r-community/blog/thoughts-on-the-nhs-r-conference.qmd"                                                                                  
[116] "/__w/nhs-r-community/nhs-r-community/blog/towards-open-health-analytics-our-guide-to-sharing-code-safely-on-github.qmd"                                          
[117] "/__w/nhs-r-community/nhs-r-community/blog/tracking-and-getting-download-statistics-for-your-r-packages.qmd"                                                      
[118] "/__w/nhs-r-community/nhs-r-community/blog/two-way-business-intelligence-partnering-shiny-and-sql-to-capture-insights-in-performance-reporting.qmd"               
[119] "/__w/nhs-r-community/nhs-r-community/blog/using-r-to-create-column-charts-featuring-95-confidence-intervals.qmd"                                                 
[120] "/__w/nhs-r-community/nhs-r-community/blog/using-r-to-track-nhs-winter-pressures.qmd"                                                                             
[121] "/__w/nhs-r-community/nhs-r-community/blog/using-rmd-for-academic-writing.qmd"                                                                                    
[122] "/__w/nhs-r-community/nhs-r-community/blog/using-sf-to-calculate-catchment-areas.qmd"                                                                             
[123] "/__w/nhs-r-community/nhs-r-community/blog/we-need-you-share-your-covid-19-work-on-nhse-is-regular-mini-huddle-series.qmd"                                        
[124] "/__w/nhs-r-community/nhs-r-community/blog/welcome-to-leeds.qmd"                                                                                                  
[125] "/__w/nhs-r-community/nhs-r-community/blog/what-a-nhs-r-community-conference-it-was-simply-wow.qmd"                                                               
[126] "/__w/nhs-r-community/nhs-r-community/blog/what-is-a-proper-data-scientist-anyway.qmd"                                                                            
[127] "/__w/nhs-r-community/nhs-r-community/blog/what-was-the-unconference.qmd"                                                                                         
[128] "/__w/nhs-r-community/nhs-r-community/blog/why-government-needs-sustainable-software-too.qmd"                                                                     

Conclusion

You can go a very long time without needing to use GitHub Actions or even spell checks on your scripts but they can be really convenient and powerful bits of code that can speed up a possibly manual process.

Back to top

Reuse

CC0