R 是一门动态类型的语言,所以通常不需要指定变量的类型。默认类型是numeric,通常实现为双精度浮点数。要强制使用 32 位整数,请加上后缀L(Long的缩写)。
获取对象的“类型”(出于历史原因)可能会让人困惑。函数typeof()和class()很相似,但返回的结果可能略有不同:
typeof(50)
#> [1] "double" # more specific: an implementation detail
typeof(50L)
##> [1] "integer"
class(50)
#> [1] "numeric" # less specific: ignores implementation details
class(50L)
#> [1] "integer"
你可能还会看到对mode()的引用,它与typeof()类似。
请忽略mode()和storage.mode()。它们只是为了向下兼容才保留的。
首选的赋值运算符是<-。如果在 RStudio 中工作,可以用快捷键Alt-minus输入。
x <- 42
avogadro <- 6.02e23
mystr <- "Hello, World!"
用=代替<-通常可行,但并非总是如此,而且被视为糟糕的风格,不推荐使用。
运算符与许多其他语言大体相似,不过%%和%/%比较特殊。这种%语法是一种调用以宏实现的中缀运算符的方式。
2 + 3 # 5
2 - 3 # -1
2 * 3 # 6
2 / 3 # 0.6666667
8 %/% 3 # 2 (integer division)
8 %% 3 # 2 (remainder)
2 ^ 3 # 8 (exponential)
在 R 中,#表示单行注释的开始。多行注释没有单独的语法。
定义一个函数:
squareit <- function(x) {
x * x
}
函数可以有零个或多个实参,用逗号分隔。即使没有形参,function()后面的圆括号()也是必需的。
可以为函数实参指定默认值,不过默认值必须放在没有默认值的实参之后,并且要用=而不是<-来赋默认值。下面是个没什么意义的例子:
squareit <- function(x = 42) {
x * x
}
squareit()
#> [1] 1764
对于单行的函数体,大括号{ }并不是严格必需的,但加上它被认为是良好的风格。
R 会自动返回函数的最后一个值,就像上面的例子那样。
return()可以用在函数体中的任何位置,以显式地给出返回值。它会立即返回指定的值并终止函数,不再执行函数体中剩余的表达式。
通常只在需要提前退出函数并出于某种原因返回特定值时,才需要显式调用return()。一个例子可能出现在if-else分支中。
不过,有些开发者出于代码风格的考虑更偏好显式返回。
调用函数的方式与许多其他语言相同:
squareit(3)
#> [1] 9
在后面的概念中我们会看到,结果9实际上是一个长度为 1 的向量,而不是标量数字。因此输出中才会带上[1],表示这是向量的开头。
is.vector(9)
#> [1] TRUE
R 中的大多数东西都是某种向量!
R 控制台会把上面的例子显示为:
> squareit(3)
[1] 9
本教学大纲中的文档大多采用一些 R 教材的惯例,去掉提示符并把结果注释出来。这样更方便把代码示例复制粘贴到控制台里运行。