←
PDF 349 / 520 output[i] <- mean(df[[i]]) } output }
→
English · PDF 349
Original PDF page 349
中文 · PDF 349

output[i] <- mean(df[[i]]) } output }

但接着你想到,如果还能计算中位数和标准差会更有帮助,于是你复制并粘贴了 col_mean() 函数,把 mean() 替换为 median() 和 sd():

col_median <- function(df) { output <- vector("double", length(df)) for (i in seq_along(df)) { output[i] <- median(df[[i]]) } output } col_sd <- function(df) { output <- vector("double", length(df)) for (i in seq_along(df)) { output[i] <- sd(df[[i]]) } output }

糟糕!你已经把这段代码复制粘贴了两次,是时候考虑如何将它泛化了。注意,这段代码的大部分都是 for 循环的样板代码,很难看出函数之间唯一不同的地方(mean()、median()、sd())。

如果你看到一组这样的函数,你会怎么做?

f1 <- function(x) abs(x - mean(x)) ^ 1 f2 <- function(x) abs(x - mean(x)) ^ 2 f3 <- function(x) abs(x - mean(x)) ^ 3

希望你能注意到其中存在大量重复,并将其提取为一个额外的参数:

f <- function(x, i) abs(x - mean(x)) ^ i

这样你减少了出 bug 的可能性(因为代码量减少了 1/3),并且更容易推广到新的情形。

我们可以对 col_mean()、col_median() 和 col_sd() 做完全一样的事情:添加一个参数,用于提供要应用到每一列的函数:

col_summary <- function(df, fun) { out <- vector("double", length(df)) for (i in seq_along(df)) {