←
PDF 310 / 520 Dot-Dot-Dot (…)
→
English · PDF 310
Original PDF page 310
中文 · PDF 310

这需要做大量额外的工作,却只带来很少的额外收益。一个有用的折中方案是内置的 stopifnot();它会检查每个参数是否为 TRUE,如果不是则产生一条通用的错误消息:

wt_mean <- function(x, w, na.rm = FALSE) { stopifnot(is.logical(na.rm), length(na.rm) == 1) stopifnot(length(x) == length(w)) if (na.rm) { miss <- is.na(x) | is.na(w) x <- x[!miss] w <- w[!miss] } sum(w * x) / sum(x) } wt_mean(1:6, 6:1, na.rm = "foo") #> 错误:is.logical(na.rm) is not TRUE

注意,使用 stopifnot() 时,你断言的是什么应该为真,而不是检查什么可能出错。

点点点(…)

R 中的许多函数接受任意数量的输入:

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) #> [1] 55 stringr::str_c("a", "b", "c", "d", "e", "f") #> [1] "abcdef"

这些函数是如何工作的?它们依赖一个特殊的参数:...(读作 dot-dot-dot,即点点点)。这个特殊参数可以捕获所有未被其他方式匹配的任意数量的参数。

它很有用,因为你可以随后将这些 ... 传递给另一个函数。如果你的函数主要是对另一个函数的封装,这是一个有用的兜底手段。例如,我经常创建这些围绕 str_c() 的辅助函数:

commas <- function(...) stringr::str_c(..., collapse = ", ") commas(letters[1:10]) #> [1] "a, b, c, d, e, f, g, h, i, j" rule <- function(..., pad = "-") { title <- paste0(...) width <- getOption("width") - nchar(title) - 5 cat(title, " ", stringr::str_dup(pad, width), "\n", sep = "") } rule("Important output") #> Important output ----------------------------------------