G. B.

个人博客

且将新火试新茶,诗酒趁年华


泛函

泛函

小知识点

  1. 注意区分:泛型函数(generic function)与泛函(functional)

    • 泛函的定义:以函数作为输入并返回一个向量的函数

    • lapply()vapply()是primitive function,它们是用C写的,尽量用它们,尽量不要使用sapply()在需要自动运行的脚本里,因为它的输出结果是不可预测的,且遇到一些问题时不会报错,使用更严谨的vapply(),或者使用lapply()在输出时固定原始对象的数据结构不变即可,如:

      mtcars[] <- lapply(mtcars, function(x) x / mean(x))
      
  2. 并行

    • parallel::mclapply()parallel::mcMap()可以实现并行计算,但只能在Unix系统中使用,windows下只能串行
    • parallel::parLapply()可以在windows使用,达到上面两个函数相同效果
  3. 三个矩阵泛函:

    • apply()

      apply(X, MARGIN, FUN, ...)的输出类型不确定,所以要留意

    • sweep()

      sweep(x, MARGIN, STATS, FUN = "-", check.margin = TRUE, ...)举个例子描述它的用法:

      x <- matrix(1:20, nrow = 5)
      x1 <- sweep(x, 1, apply(x, 1, min), `-`)
      x2 <- sweep(x1, 1, apply(x1, 1, max), `/`)
      

      即x按行依次减去x每一行对应的最小值得到x1 x1按行除以x1每一行对应的最大值得到x2

    • outer() outer(X, Y, FUN = "*", ...)默认计算X与Y的外积,但也可以指定其他的FUN,会对输入的所有可能组合进行计算

  4. 数组泛函

    tapply(X, INDEX, FUN = NULL, ..., default = NA, simplify = TRUE)
    

    它可以应用于不规则的数组,数组中的每一行都可以有不同的列数,它的思想其实可以重写为:

    tapply <- function(x, group, f, ..., simplify = TRUE) {
      pieces <- split(x, group)
      sapply(pieces, f, simplify = TRUE)
    }
    

    其中split()按照group对x分组,返回一个list

  5. 基础包中的泛函命名不一致,参数设置不一致,且没有覆盖全数据类型

    输入类型、输出类型 列表 数据框 数组
    列表 lapply   sapply
    数据框 by    
    数组     apply

    plyr包提供一致性参数并涵盖所有数据类型

    输入类型、输出类型 列表 数据框 数组
    列表 llply ldply laply
    数据框 dlply ddply daply
    数组 alply adply aaply
  6. 递归

    Reduce(f, x, init, right = FALSE, accumulate = FALSE)
    

    通过递归调用函数f(),将向量x计算成一个值,例:

    Reduce(`+`, 1:3)
    

    即就是((1 + 2) + 3),参数right可以使递归从向量x的右段开始,init初始值,accumulate控制是否输出中间结果

  7. 三个基础包中的判断泛函:
    • Filter()只选择满足判断条件的元素
    • Find()返回满足判断条件的第一个元素(如果right = TRUE则最后一个元素)
    • Position()返回满足判断条件的第一个元素的位置(如果right = TRUE则最后一个元素)
  8. 三个数学泛函:
    • integrate()计算定积分
    • uniroot()计算f() = 0的点集
    • optimize()计算f()最高点和最低点的位置