33

in Python I'm used to having my code "style-checked" by an automatic but configurable tool, called pep8, after the 8th Python enhancement proposal.

in R I don't know. Google has a style guide, but:

  • what do most R programmers actually use?
  • I still didn't find any program that performs those checks.

Dirk, Alex, in your answers you pointed me at pretty printers, but in my opinion that would overdo one thing and not do another: code would be automatically edited to follow the style, while no warnings are issued for poorly chosen identifiers.

JJJ
  • 32,902
  • 20
  • 89
  • 102
mariotomo
  • 9,438
  • 8
  • 47
  • 66
  • Related question : http://stackoverflow.com/questions/4406873/coding-practice-in-r-what-are-the-advantages-and-disadvantages-of-different-sty – Joris Meys Feb 25 '11 at 13:28
  • The other style guide that's available is [Henrik Bengtsson's](https://docs.google.com/document/preview?id=1esDVxyWvH8AsX-VJa-8oqWaHLs4stGlIbk8kLc5VlII&pli=1#heading=h.f456284e7686). A canonical one would be nice, but there ain't one (and there's plenty of disagreement between the existing ones) – naught101 May 29 '12 at 13:17
  • 2
    This could be useful: http://cran.r-project.org/web/packages/lint/lint.pdf – waferthin Apr 09 '14 at 12:13
  • 2
    As I mentioned in a comment further down the page, the [goodpractice](https://cran.r-project.org/web/packages/goodpractice/index.html) R module gives "... advice about good practices when building R packages. Advice includes functions and syntax to avoid, package structure, code complexity, code formatting, etc." I believe it uses lintr and other similar R packages internally and is under somewhat active development on [github](https://github.com/MangoTheCat/goodpractice). – makeyourownmaker Aug 24 '18 at 12:37

7 Answers7

21

There's a formatR package with tidy.source function. I use Emacs with ESS, and follow Hadley's style recommendations. It's hard to compare R with Python, since style is kind of mandatory in Python, unlike R. =)

EDIT
a simple demonstration:

code <- "fn <- function(x, y) { paste(x, '+', y, '-', x+y) }"
tidy.source(text = code)
## not run
fn <- function(x, y) {
    paste(x, "+", y, "-", x + y)
}
aL3xa
  • 35,415
  • 18
  • 79
  • 112
  • 2
    which looks useful for poorly formatted code you inherited somehow. but I'm looking for something different, that just tells me where I'm not following a style, leaving me the task to do something about it (or not). – mariotomo Feb 26 '11 at 09:16
  • I'm not sure if there's a tool like that, but thank you for giving me an idea for a web-application. =) – aL3xa Feb 26 '11 at 11:44
  • why a "web-application"? anyhow, if you GPL it and hold the sources on a public repository, I'd be interested in following the development! – mariotomo Mar 04 '11 at 10:53
  • well... because I tend to think of myself as a web-developer (apart from the gig in statistics and R). It shouldn't be that hard... I guess =) And yes, if I decide to develop a tool like that, it's definitely going to published under GPL. It makes no sense otherwise... – aL3xa Mar 04 '11 at 18:32
11

I think if you want such a tool, you may have to write it yourself. The reason is that R does not have an equivalent to Python's PEP8; that is, an "official style guide" that has been handed down from on high and is universally followed by the majority of R programmers.

In addition there are a lot of stylistic inconsistencies in the R core itself; this is a consequence of the way in which R evolved as a language. For example, many functions in R core follow the form of foo.bar and were written before the S3 object system came along and used that notation for method dispatch. In hindsight, the naming of these functions should probably be changed in the interests of consistency and clarity, but it is too late to consider that now.

In summary, there is no official "style lint" tool for R because the R Core itself contains enough style lint, of which nothing can be done about, that writing one would be very difficult. For every rule--- "don't do this" ---there would have to be a long list of exceptions--- "except in this case, and this case, and this one, and ..., where it was done for historical purposes".

xiaodai
  • 14,889
  • 18
  • 76
  • 140
Sharpie
  • 17,323
  • 4
  • 44
  • 47
  • writing it myself, I was already considering it, either by altering the R compiler or by adapting an other "lint" to work with R. but I am aware that this is a huge enterprise. – mariotomo Feb 27 '11 at 09:11
  • 1
    but, about the too many styles in the R Core, I don't see the problem: a style checker would complain about what I *define*, not about what I *use*. and I would not ask it to check the R Core! :) – mariotomo Feb 27 '11 at 09:13
  • starting from the wikipedia page for lint, I stumbled upon [Yasca](http://en.wikipedia.org/wiki/Yasca). what about a [plugin](http://www.scovetta.com/yasca/creating-a-plugin.html) for it? – mariotomo Feb 27 '11 at 10:30
  • @moriotomo: Functions from R Core provide many of the building blocks for user code. The more core functions you end up using in your own code, the more intelligent your style checker will have to be. – Sharpie Feb 28 '11 at 05:43
  • 2
    Hadley's recs are for the most part followed by [`lintr`](https://github.com/jimhester/lintr?files=1). – bright-star Jan 05 '15 at 00:41
6

As for

what do most R programmers actually use

I suspect that quite a few people follow R Core who have a R Coding standards section in the R Internals manual.

Which in a large sense falls back to these sensible Emacs defaults to be used along with ESS. Here is what I use and it is only minimally changed:

;;; C
(add-hook 'c-mode-hook
          ;;(lambda () (c-set-style "bsd")))
          ;;(lambda () (c-set-style "user"))) ; edd or maybe c++ ?
          (lambda () (c-set-style "c++"))) ; edd or maybe c++ ?
;;;; ESS
(add-hook 'ess-mode-hook
          (lambda ()
            (ess-set-style 'C++)
        ;; Because
            ;;                                 DEF GNU BSD K&R C++
            ;; ess-indent-level                  2   2   8   5   4
            ;; ess-continued-statement-offset    2   2   8   5   4
            ;; ess-brace-offset                  0   0  -8  -5  -4
            ;; ess-arg-function-offset           2   4   0   0   0
            ;; ess-expression-offset             4   2   8   5   4
            ;; ess-else-offset                   0   0   0   0   0
            ;; ess-close-brace-offset            0   0   0   0   0
            (add-hook 'local-write-file-hooks
                      (lambda ()
                        (ess-nuke-trailing-whitespace)))))
(setq ess-nuke-trailing-whitespace-p t)

As for a general, tool Xihui's formatR pretty-printer may indeed be the closest. Or just use ESS :)

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
4

The lint package gives warnings about stylistic problems, without correcting those. Running the lint() command (using the default parameter values) gives you a list of warnings for all R files in the current directory.

  • 3
    The lint package has been archived on CRAN sometime between now and when this answer was made, which may mean it is no longer a good option for consideration. – makeyourownmaker Mar 01 '17 at 16:28
  • 1
    @makeyourownmaker There is however the newer [lintr](https://cran.r-project.org/web/packages/lintr/index.html) (@USER_1 mentions it in their answer below). Its newer and maintained. – slackline Aug 23 '18 at 08:45
  • @slackline The [goodpractice](https://cran.r-project.org/web/packages/goodpractice/index.html) R module gives "... advice about good practices when building R packages. Advice includes functions and syntax to avoid, package structure, code complexity, code formatting, etc." I believe it uses lintr and other similar R packages internally and is under somewhat active development on [github](https://github.com/mangothecat/goodpractice). – makeyourownmaker Aug 24 '18 at 12:25
4
USER_1
  • 2,409
  • 1
  • 28
  • 28
4

I use styler and then lintr before I check anything into version control.

styler converts your code base to match a given style - the default matches the tidyverse style described here. It modifies alignments, and some syntax (<- over =). But, it doesn't rename variables or anything like that.

lintr is non-modifying. It just identifies lines of code that are inconsistent with your style guide. I use this within vim when I'm working on a package or a project to identify things that need a bit more human input to fix (renaming variables/functions etc)

Russ Hyde
  • 2,154
  • 12
  • 21
1

RStudio has added a style checker at some point in the past. For instance, in version 1.1.463 you can enable the feature under General Options. Here's a screenshot:

enter image description here

Waldir Leoncio
  • 10,853
  • 19
  • 77
  • 107