←
PDF 298 / 520 As you write more and more functions you'll eventually want to convert these informal, interacti
→
English · PDF 298
Original PDF page 298
中文 · PDF 298

当你编写越来越多的函数时,最终你会想把这些非正式的交互式测试转换成正式的自动化测试。这个过程叫做单元测试。遗憾的是,这超出了本书的范围,但你可以在 http://rpkgs.had.co.nz/tests.html 上学习相关知识。

既然我们已经有了一个函数,就可以简化最初的示例:

df$a <- rescale01(df$a) df$b <- rescale01(df$b) df$c <- rescale01(df$c) df$d <- rescale01(df$d)

与原始代码相比,这段代码更容易理解,而且我们消除了一类复制粘贴错误。不过仍然存在相当多的重复,因为我们对多个列执行了相同的操作。等你学完第 16 章中关于 R 数据结构的更多内容后,我们将在第 17 章学习如何消除这种重复。

函数的另一个优点是,如果需求发生变化,我们只需要在一个地方进行修改。例如,我们可能发现某些变量包含无穷值,而 rescale01() 会失败:

x <- c(1:10, Inf) rescale01(x) #> [1] 0 0 0 0 0 0 0 0 0 0 NaN

因为我们已经把代码提取成了函数,所以只需要在一个地方进行修复:

rescale01 <- function(x) { rng <- range(x, na.rm = TRUE, finite = TRUE) (x - rng[1]) / (rng[2] - rng[1]) } rescale01(x) #> [1] 0.000 0.111 0.222 0.333 0.444 0.556 0.667 0.778 0.889 #> [10] 1.000 Inf

这是“不要重复自己”(DRY)原则的重要组成部分。代码中的重复越多,当情况发生变化时(变化总是会发生!),你需要记住更新的地方就越多,随着时间推移产生 bug 的可能性也就越大。