函数式编程
函数式编程有三块内容:
- 匿名函数
- 闭包
- 函数列表
举个例子:
set.seed(1024)
df <- data.frame(replicate(6, sample(c(1:10,-99), 6, replace = T)))
names(df) <- letters[1:6]
df
> df
a b c d e f
1 9 9 4 5 6 6
2 9 3 5 4 -99 8
3 6 5 1 5 3 3
4 -99 2 1 4 -99 2
5 5 3 9 6 2 4
6 2 9 4 7 -99 7
现在我要将-99全部处理成为缺失值,一般新手都会这样做:
df$a[df$a == -99] <- NA
df$b[df$b == -99] <- NA
df$c[df$c == -98] <- NA
df$d[df$d == -99] <- NA
df$e[df$e == -99] <- NA
df$f[df$g == -99] <- NA
# 当你第一次写R语言的时候,你可能会这样写,但是这样非常容易出现错误
这样非常容易出现错误
有一个原则
do not repeat yourself
这个原则是指:
在一 个体系中,每个知识都必须有一个明确的、权威的表达
你应该这样写:
fix_missing <- function(x) {
x[x == -99] <- NA
x
}
df$a <- fix_missing(df$a)
df$b <- fix_missing(df$b)
df$c <- fix_missing(df$c)
你明白了吗,使用函数去替代那些重复的工作
再结合apply就能够更加快捷的处理这个问题了
泛函
lapply
被称之为泛函,因为其接受一个函数作为参数
df[] <- lapply(df, fix_missing)
这种做法的优点:
- 它更紧凑。
- 如果缺失值的代码发生变化,只需要更新一个地方。
- 它适用于任何数量的列。 不会错过任何一列。
- 不会让一列的操作与另一列不同。
- 很容易把这种技术推广到列的一个子集:
闭包
返回函数的函数
匿名函数
没有名字的函数,一般在函数内部使用
summary <- function(x) {
funs <-
c(mean, median, sd, mad, IQR) lapply(funs, function(f)
f(x, na.rm = TRUE))
}
你没有给函数命名的时候就会得到一个匿名函数
匿名函数最常见的用途就是创建一个闭包
power <- function(exponent) {
function(x) {x ^ exponent
}
}
a <- power(2)
不同层次管理变量需要使用双箭头
<<-
另外,可以将函数存放在同一个列表里面,调用的时候也非常的简单
compute_mean <- list(
base = function(x) mean(x),
sum = function(x) sum(x) / length(x), manual = function(x) {
total <- 0
n <- length(x)
for (i in seq_along(x)) {
total <- total + x[i] / n
}
total
}
)
system.time(compute_mean$base(runif(100)))
system.time(compute_mean$sum(runif(100)))
system.time(compute_mean$manual(runif(100)))
想要调用每一个函数,就可以使用
lapply(compute_mean, function(f) f(x))
网友评论