小洁详解《R数据科学》--第十四章 函数

终于学到了写函数,省时省力呀。

1.居然没有准备工作。

2.使用函数的情况:同样的数据需要多次重复

先理解一下range函数:输入一个向量,返回其最小值和最大值。

y <- range(c(1,3,-1))
y #最小值和最大值
#> [1] -1  3
y[1] #最小值
#> [1] -1

写成函数

rescale01 <- function(x) {
rng <- range(x, na.rm = TRUE)
(x - rng[1]) / (rng[2] - rng[1])
}
rescale01(c(0, 5, 10))
#> [1] 0.0 0.5 1.0

我写了一个更简单的函数帮助理解

doodle <- function(x){
  range(x)-3
}
doodle(c(1, 2, 3, NA, 5))
#> [1] NA NA

创建函数的关键步骤:命名、参数、函数体

3.函数命名

函数名是动词,参数名是名词。

多个单词组成的函数名用snake_case命名法。即用下划线连接。

一族函数,可以加通用前缀。

4.条件执行

(1)condition

模板

if (condition) {

} else {

}

i=8
 if(i<5){
    "doudou"
  }else{
    "huahua"
  }
#> [1] "huahua"

condition是逻辑值。

补充操作:ifelse(test,yes,no)

x <- c(3,4,6)
ifelse(x>5,x+3,x-3)
#> [1] 0 1 9

整数和双精度浮点数

  • 先看类型
class(0L)
#> [1] "integer"
class(0)
#> [1] "numeric"
  • 判断是否相等
sqrt(2) ^ 2==2
#> [1] FALSE
identical(sqrt(2) ^ 2,2)
#> [1] FALSE
  • 解决办法
dplyr::near(sqrt(2) ^ 2,2) 
#> [1] TRUE

(2)多重条件

入门操作

if (this) {

} else if (that) {

} else {

}

升级操作:switch
biu <- function(x, y, op) {
  switch(op,
  plus = x + y,
  minus = x - y,
  times = x * y,
  divide = x / y,
  stop("Unknown op!")
  )
}
x <- biu(3,5,"divide")
#此处注意这三个输入参数分别是两个数字和一个运算方式。如果是三个数字则计算结果为NULL
升级操作:cut

按照坐标划分区间。

temp <- seq(-10, 50, by = 5)
cut(temp, c(-Inf, 0, 10, 20, 30, Inf), right = TRUE,
    labels = c("freezing", "cold", "cool", "warm", "hot"))
#>  [1] freezing freezing freezing cold     cold     cool     cool    
#>  [8] warm     warm     hot      hot      hot      hot     
#> Levels: freezing cold cool warm hot
#right:logical, indicating if the intervals should be closed on the right (and open on the left) or vice versa.

查看cut的帮助文档得知,参数right=TRUE表示左开右闭,right=FALSE表示左闭右开。
(3)代码风格
代码短则可以不用大括号,一行写开。(不推荐)
大括号内的内容缩进。
大括号单独占一行或跟else。

5.函数参数

函数的参数分数据和细节两类。细节参数有默认值。
加空格:符号前后。注意逗号只在后面加,不在前面加。

(1)选择参数名称

(2)检查参数值

生成报错:

stop
wt_mean <- function(x, w) {
if (length(x) != length(w)) {
stop("`x` and `w` must be the same length", call. = FALSE)
}
sum(w * x) / sum(x)
}
stopifnot
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)
}

(3)点点点(...)

作用:接受任意数量的输入

6.返回值

(1)提前返回--return

简单的情况写在if,复杂的写在else。
好用的思路:if(!x)

(2)支持管道操作

支持管道操作的函数:

转换函数--计算
副作用函数--执行某种行为,比如绘图、保存。

7.环境

R会在定义函数的环境中寻找没有定义的变量。
可以编写函数覆盖默认的函数。(好像暂时用不到)

微信公众号生信星球同步更新我的文章,欢迎大家扫码关注!


我们有为生信初学者准备的学习小组, 点击查看◀️
想要参加我的线上线下课程,也可加好友咨询
如果需要提问,请先看 生信星球答疑公告

你可能感兴趣的:(小洁详解《R数据科学》--第十四章 函数)