# install.packages('pak')
pak::pak('mjfrigaard/shinypak')32 Code style
βWeβre in the business of keystrokes and neuronsβ
During development, it can be challenging to keep the code in your app-package clean and perfectly formatted. Fortunately, the R ecosystem has some excellent tools for making your code functional and easy to read.
32.1 Code style and formatting
The lintr and styler packages in R serve related but distinct purposes and have different focuses in their functionality. The primary difference between lintr and styler is that styler can automatically fix any stylistic issues it identifies in your code (rather than just reporting them).
Launch app with the shinypak package:
launch('31_style')32.1.1 lintr
lintr is a static code analysis tool used to identify syntax errors, semantic issues, and violations of stylistic guidelines in your code. The package contains a list of βlintersβ for various potential problems and can be customized according to your needs. lintr is designed to help improve your codeβs quality and readability by generating reports in the βmarkersβ pane. Running lintr wonβt automatically correct the identified issues (youβll need to fix the linting issues it reports manually).
32.1.2 styler
On the other hand, the purpose of styler is to ensure consistency in the code formatting, which is crucial if youβre working in a team or contributing to open-source projects (like tidyverse packages). The styler package will change your codeβs format according to specified style guidelines. These changes include indentation, spaces, and line breaks that adhere to your style guidelines.
While there is some overlap (both packages can help enforce coding style guidelines), lintr is a more general tool for code quality, spotting potential issues and bugs. At the same time, styler focuses on code formatting and can automatically apply fixes. Many developers find combining both can help catch potential issues and ensure a consistent, readable coding style.
32.2 Checking your code
Iβve previously mentioned running devtools::check() can be overkill for your app-package (especially if itβs not destined for CRAN). A nice alternative to check() is the goodpractice package..
goodpractice::gp() inspects your package and prints any areas that might need βgood practiceβ advice:
library(goodpractice)
pkg_checks <- gp(path = ".")
pkg_checksPreparing: description
Preparing: lintr
  |====================================================================| 100%
Preparing: namespace
Preparing: rcmdcheck
ββ GP sap βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
It is good practice to
  β add a "URL" field to DESCRIPTION. It helps users find information about your
    package online. If your package does not have a homepage, add an URL to 
    GitHub, or the CRAN package package page.
  β add a "BugReports" field to DESCRIPTION, and point it to a bug tracker. 
    Many online code hosting services provide bug trackers for free, 
    https://github.com, https://gitlab.com, etc.
  β avoid long code lines, it is bad for readability. Also, many people prefer 
    editor windows that are about 80 characters wide. Try make your lines 
    shorter than 80 characters
    data-raw/tidy_movies.R:49:81
    R/data.R:4:81
    R/data.R:7:81
    R/data.R:17:81
    R/data.R:21:81
    ... and 13 more lines
  β not import packages as a whole, as this can cause name clashes between the 
    imported packages. Instead, import only the specific functions you need.
  β fix this R CMD check NOTE: display_type: no visible binding for global 
    variable
    β.rs.invokeShinyPaneViewerβ display_type: no visible binding for global 
    variable
    β.rs.invokeShinyWindowExternalβ display_type: no visible binding for global
    variable
    β.rs.invokeShinyWindowViewerβ mod_scatter_display_server : <anonymous>: no 
    visible binding for global
    variable βmoviesβ Undefined global functions or variables: 
    .rs.invokeShinyPaneViewer 
    .rs.invokeShinyWindowExternal 
    .rs.invokeShinyWindowViewer 
    moviesWe can also check specific components of our package by looking up the available checks in all_checks():
grep("import", x = all_checks(), value = TRUE)[1] "no_import_package_as_a_whole"                 
[2] "rcmdcheck_undeclared_imports"                 
[3] "rcmdcheck_imports_not_imported_from"          
[4] "rcmdcheck_depends_not_imported_from"          
[5] "rcmdcheck_triple_colon_imported_objects_exist"
[6] "rcmdcheck_unexported_base_objects_imported"   
[7] "rcmdcheck_unexported_objects_imported"        
[8] "rcmdcheck_empty_importfrom_in_namespace"  All of the checks with the rcmdcheck_ prefix are part of the R CMD check diagnostic, but goodpractice comes with other checks that are good practices (even if youβre not submitting your package to CRAN).
For example, no_import_package_as_a_whole checks the practice we covered in managing imports. If we pass the no_import_package_as_a_whole check as a character vector to the checks argument:
gp(path = ".", checks = 'no_import_package_as_a_whole')Only this check is performed:
ββ GP sap βββββββββββββββββββββββββββββββββββββββββββββββββββ
It is good practice to
  β not import packages as a whole, as this can cause name clashes between
    the imported packages. Instead, import only the specific functions you need.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ32.3 Recap
This chapter covered an introduction to some tools and practices for improving and maintaining the quality of the code in your app-package. Maintaining code style and standards (lintr and styler) and performing thorough checks to adhere to best practices (goodpractice) will ensure efficient and reliable development and deployment for your app.