美文网首页R语言
函数式编程/R

函数式编程/R

作者: Liam_ml | 来源:发表于2018-09-10 14:25 被阅读13次

函数式编程

函数式编程有三块内容:

  • 匿名函数
  • 闭包
  • 函数列表

举个例子:

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)

这种做法的优点:

  1. 它更紧凑。
  2. 如果缺失值的代码发生变化,只需要更新一个地方。
  3. 它适用于任何数量的列。 不会错过任何一列。
  4. 不会让一列的操作与另一列不同。
  5. 很容易把这种技术推广到列的一个子集:

闭包

返回函数的函数

匿名函数

没有名字的函数,一般在函数内部使用

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))

相关文章

网友评论

    本文标题:函数式编程/R

    本文链接:https://www.haomeiwen.com/subject/fejsgftx.html