DarkMatter in Cyberspace
  • Home
  • Categories
  • Tags
  • Archives

R Style Guide


R Style Guide

综述

R 使用了 Java/C 基于大括号的自由编码风格,对不规范的编码格式容忍度较高。 但为了提高代码可读性,开发者仍然应遵守社区的最佳实践规范。

作为一种面向数据分析的编程语言,尽量使用 tidyverse 包实现应用功能, 配合使用 styler 和 lintr 做格式化检查工具。

命名规则

有效的命名风格:

  • lowercase

  • lower_case_with_underscores

  • UPPERCASE

  • UPPER_CASE_WITH_UNDERSCORES

  • CapWords

文件

文件名使用 lower_case_with_underscores 风格,并以 R 作为扩展名:

# Good
fit_models.R
utility_functions.R

# Bad
fit models.R
foo.r
stuff.r

语法

变量和函数名称

变量和函数名使用 lower_case_with_underscores 风格, 变量一般为名词,函数一般为动词:

# Good
day_one
day_1

# Bad
DayOne
dayone

不要使用 . 作为名称内部分隔符。

避免使用常用的函数名作为变量名,例如:

mean <- function(x) sum(x)

空格

逗号前面不要有空格,后面保证有且只有一个空格:

# Good
x[, 1]

# Bad
x[,1]
x[ ,1]
x[ , 1]

函数调用时,括号两侧不要有空格:

# Good
mean(x, na.rm = TRUE)

# Bad
mean (x, na.rm = TRUE)
mean( x, na.rm = TRUE )

if, for, while 语句的括号两侧保留一个空格:

if (debug) {
  show(x)
}

# Bad
if(debug){
  show(x)
}

函数定义时,参数列表和函数体中间保留一个空值:

# Good
function(x) {}

# Bad
function (x) {}
function(x){}

二元操作符两侧各保留一个空格:

# Good
height <- (feet * 12) + inches
mean(x, na.rm = 10)

# Bad
height<-feet*12+inches
mean(x, na.rm=10)

行尾不要留有空格。

代码块

R 的代码块书写规则:

  • 左大括号是一行代码的结尾字符,不要单起一行;

  • 每层缩进使用两个空格;

  • 右大括号单起一行,且只有这一个字符;

示例:

# Good
if (y < 0 && debug) {
  message("y is negative")
}

if (y == 0) {
  if (x > 0) {
    log(x)
  } else {
    message("x is negative or zero")
  }
} else {
  y^x
}

test_that("call1 returns an ordered factor", {
  expect_s3_class(call1(x, y), c("factor", "ordered"))
})

tryCatch(
  {
    x <- scan()
    cat("Total: ", sum(x), "\n", sep = "")
  },
  interrupt = function(e) {
    message("Aborted by user")
  }
)

# Bad
if (y < 0 && debug) {
message("Y is negative")
}

if (y == 0)
{
    if (x > 0) {
      log(x)
    } else {
  message("x is negative or zero")
    }
} else { y ^ x }

折行

每行长度原则不超过80个字符,如果一个函数调用太长,写成每行一个参数的形式:

# Good
do_something_very_complicated(
  something = "that",
  requires = many,
  arguments = "some of which may be long"
)

# Bad
do_something_very_complicated("that", requires, many, arguments,
                              "some of which may be long"
                              )

赋值

使用 <- 给变量赋值,不要使用 =:

# Good
x <- 5

# Bad
x = 5

分号

不要在语句之间和语句结尾使用分号。

引号

当文本内没有双引号时,使用双引号引用文本,否则使用单引号:

# Good
"Text"
'Text with "quotes"'
'<a href="http://style.tidyverse.org">A link</a>'

# Bad
'Text'
'Text with "double" and \'single\' quotes'

注释

在数据分析代码中,使用注释重要的发现和分析结果。 如果需要通过注释表达代码的意图,尝试改写代码,尽量将意图体现在代码中。 如果某些 why 不能很好地以代码的形式表达,可以记录在注释中,但不要在注释中写 what 和 how。 如果注释比代码多,用 Rmarkdown 代替 R 脚本文件。

函数返回

只在提前返回时使用 return() 函数,否则使用 R 的“返回最后一个表达式”规则,不显式使用 return():

# Good
find_abs <- function(x) {
  if (x > 0) {
    return(x)
  }
  x * -1
}
add_two <- function(x, y) {
  x + y
}

# Bad
add_two <- function(x, y) {
  return(x + y)
}

return() 语句单独写一行:

# Good
find_abs <- function(x) {
  if (x > 0) {
    return(x)
  }
  x * -1
}

# Bad
find_abs <- function(x) {
  if (x > 0) return(x)
  x * -1
}

管道操作符

管道操作符左侧有一个空格,右侧是行尾,不要加空格,原则上每行一个管道操作:

# Good
iris %>%
  group_by(Species) %>%
  summarize_if(is.numeric, mean) %>%
  ungroup() %>%
  gather(measure, value, -Species) %>%
  arrange(value)

# Bad
iris %>% group_by(Species) %>% summarize_all(mean) %>%
ungroup %>% gather(measure, value, -Species) %>%
arrange(value)

如果一个表达式中只有一个管道操作,且后续不存在扩展的可能,改成普通函数形式:

# Good
arrange(iris, Species)

# Bad (when no plan to expand it later on)
iris %>% 
  arrange(Species)

参与管道操作的函数如果没有参数,magrittr 允许不写括号,不要使用这一特性:

# Good
x %>% 
  unique() %>%
  sort()

# Bad
x %>% 
  unique %>%
  sort

通过管道为变量赋值:

iris_long <- iris %>%
  gather(measure, value, -Species) %>%
  arrange(-value)

不要使用 %<>% 操作符:

# Good
x <- x %>% 
  abs() %>% 
  sort()

# Bad
x %<>%
  abs() %>% 
  sort()

文档

R 的 roxygen2 类似于 Java 的 JavaDoc, 将代码中符合指定格式的代码注释转换为 HTML 格式文档。

环境和依赖管理

R 的 packrat 大致相当于 Java 的 Maven 和 Python 的 pipenv。

最简工作流程:

library(packrat)
init("~/docs/myproject")  # initialize project scaffold
install.packages('rmarkdown')
install.packages('tidyverse')
status()
snapshot()   # download package source code into packrat/src

packrat/src 目录下保存依赖库的源码压缩包,库版本保存在 packrat/packrat.lock 文件中, 配置信息保存在 packrat/packrat.opts 文件中。

packrat 默认会把压缩的源码包提交到版本控制系统中,当在新环境中 clone 出这个代码库并用 RStudio 打开这个 R Project 时, 会自动在项目私有环境中安装 packrat,在 RStudio 中执行下面的命令重建环境:

library(packrat)
status()  # optional
restore()

使用 install.packages() 安装新的依赖库后, 执行 snapshot() 会下载这些依赖库的源码压缩包到 packrat/src 目录下。 并更新 packrat/packrat.lock 文件。

如果当前环境中不包含所有被 snapshot 的 package,status() 会报告, 如果新安装的包还没有 snapshot,status() 不会报告。



Published

Jul 15, 2019

Last Updated

Jul 15, 2019

Category

Tech

Tags

  • rlang 17
  • znbt 6

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor