Photo by Waldemar Brandt on Unsplash

lintr v2.0.0

lintr 2.0.0 is now on CRAN!

lintr checks adherence to a given style, looks for syntax errors and possible semantic errors. It is useful for automatically checking code style on CI systems such as Travis CI, as well as local checking of R code edited with the RStudio IDE, Emacs, Vim, Sublime Text and Atom.

This release is version 2.0.0 to signify it is a major release, containing changes that have been in the devel branch since the last major release (1.0.0) on 2016-04-16, three and a half years ago! There have been a few minor bugfix releases since that time, but many new linters have only been available in the devel version of lintr. See the full Changelog for details on all of the changes.

New linters

There are a number of new linters available in this release. Not all of them are enabled by default, you can add a specific linter to the defaults by using with_defaults() and the linters argument, e.g.

lint_package(linters = with_defaults(extraction_operator_linter()))
  • cyclocomp_linter() - identifies overly complex functions
  • equals_na_linter() - finds cases where code tries to check x == NA rather than
  • extraction_operator_linter() - checks that the [[ operator is used when extracting a single element from an object, not [ (subsetting) nor $ (interactive use)
  • function_left_parentheses_linter() - to check that there is no space between a function name and its left parentheses
  • implicit_integer_linter() - detects round numbers not declared as integers, i.e. 1 instead of 1L
  • nonportable_path_linter() - identifies paths constructed without file.path()
  • paren_brace_linter() - checks that there is a space between right parenthesis and an opening curly brace
  • pipe_continuation_linter() - to ensure there is a space before %>% and newline afterwards
  • semicolon_terminator_linter() - reports semicolons at the end a line and between expressions
  • seq_linter() - finds 1:length(...) (and similar) expressions
  • todo_comment_linter() - lints TODOs
  • T_and_F_symbol_linter() - warns when using T and F instead of TRUE and FALSE
  • undesirable_operator_linter() - and undesirable_function_linter() lint uses of user-specified functions and operators
  • unneeded_concatenation_linter() - lints uses of c() with a constant or no arguments

New functions

There are a handful of new functions available in this release.

  1. lint_dir() - Run lintr on any arbitrary directory, this is useful when you have a collection of scripts, but they aren’t in a formal package.
  2. checkstyle_output() - Output the lints in the checkstyle format often used in Java applications. Many programs can read this format, so this allows lintr results to be used.
  3. summary.lints() - You can now call summary() on your lint results to get a summation of the issues.

New functions for writing linters

Writing custom linters in your own package is now easier thanks to more of these internal functions being exported from lintr. See the creating linters vignette on information on how to create a new linter, and if you find additional functions are necessary please open an issue.


There are a large number of bugfixes, see the full Changelog for details. Many of these fixes were submitted by community members, a huge thanks to everyone who contributed!

Become a maintainer!

The lintr package is looking for new contributors and maintainers, if you use lintr in your work and think it could be improved please consider joining the project. You can also join our gitter chatroom if you are interested in helping. Join the chat at


This release would not have been possible without the contributions from the community. I would like to thank in particular Florent Angly (@fangly) and Russ Hyde (@russHyde). Florent did a large amount of work making existing linters much more robust and adding new linters and Russ has been a great help recently triaging issues and fixing bugs.

Also a huge thanks to all the rest of the 143 people who contributed code and opened issues for lintr 2.0.0!

@AdamSpannbauer, @Agent-Sesame, @aksh7860, @alessandro-gentilini, @alex88, @AlexAxthelm, @andrewychoi, @angrygoats, @apandit24, @Arcanemagus, @arekbee, @arnyeinstein, @artemklevtsov, @azoimide, @batpigandme, @benman1, @BenoitLondon, @bfgray3, @blindjesse, @bmwilly, @bnsh, @brnleehng, @byapparov, @cboettig, @cdiener, @cnolanminich, @csgillespie, @cwhoffmannch, @dchiu911, @denrou, @dfrankow, @dirkschumacher, @dirmeier, @dragosmg, @dschlaep, @dy-kim, @edlee123, @EdwinTh, @ellisvalentiner, @EmilRehnberg, @Enchufa2, @EndenDragon, @even4void, @fabian-s, @Fablepongiste, @fangly, @FerandDalatieh, @flodel, @flying-sheep, @FvD, @gaborcsardi, @gdbassett, @gdequeiroz, @gdkrmr, @ghost, @ginberg, @gitter-badger, @giuseppec, @GregoireGauriot, @GregorDeCillia, @grssnbchr, @Guillawme, @ha0ye, @hadley, @hanfeisun, @harryln, @hfrick, @Hong-Revo, @hstahl, @HyukjinKwon, @IndrajeetPatil, @infotroph, @jabranham, @jackwasey, @javierluraschi, @jayvdb, @jcubic, @jennybc, @jeremymiles, @JhossePaul, @jimhester, @jmwerner, @jonmcalder, @joshkgold, @jrnold, @jvd10, @karawoo, @kenahoo, @khughitt, @LiNk-NY, @LukeGoodsell, @maelle, @mattiaciollaro, @mattyb, @maxheld83, @mb706, @md0u80c9, @michaellevy, @mindlessroman, @mjsteinbaugh, @mpadge, @mplough, @mschilli87, @mwaldstein, @nathaneastwood, @naught101, @pachevalier, @paulkaefer, @peterhurford, @petobens, @prosoitos, @q23qweliuhan, @qianchd, @quartin, @rafazaya, @randy3k, @rentrop, @richelbilderbeek, @RMHogervorst, @rmsharp, @robinklaassen, @rpietro, @russHyde, @SchalkWBurger, @schloerke, @sfr, @shashj199, @slmagus, @smilesun, @stefanoborini, @step-, @stufield, @taqtiqa-mark, @TARehman, @ThierryO, @tvatter, @w0rp, @wamserma, @WilDoane, @wlandau, @xiamaz, @yitang, and @zero323

Jim Hester
Software Engineer

I’m a Senior Software Engineer at Netflix and R package developer.