北京大学生物信息平台论坛

 找回密码
 立即注册
搜索
热搜: 通知 活动

R 学习笔记:R 函数

[复制链接]
wolf 发表于 2016-4-30 13:37:50 | 显示全部楼层 |阅读模式
本帖最后由 wolf 于 2016-5-11 19:28 编辑

R 中的许多对数据的处理需要用函数来完成, 要么使用别人编写好的函数, 要么使用自己去写的函数. 所以, 知道 R 语言中的函数是什么, 该怎么用是十分有必要的.R 语言中的函数, 有的使用 R 语言去写的, 有的则考虑到性能等原因使用 C/C++ 等语言来写. 使用非 R 语言写的函数和 R 语言写的函数是有差别的. 下面主要考虑 R 语言编写的函数吧.
函数结构



一个 R 函数有三个部分: 函数体 (body); 参数 (formals); 环境 (environment). 对于一个函数, 可以使用 body(), formals(), environment() 等函数可以去查看函数的这些部分.

对象查找



函数中的对对象查找是有一定的顺序的. R 语言中的名称域查找有两类: 词法域 (lexical scoping), 默认查找的方式; 动态域 (dynamic scoping), 在交互式操作的运行中可以减少输入.
词法域 (lexical scoping) 查找有四个基本概念.
  • 名称覆盖 (name masking): 首先查找函数体内的对象是否有符合对应名称的变量, 如果没有的话, 就再上升一个层次继续查找.
  • 方程和变量 (functions v.s. variables): 如果方程和变量的名称一样的话, 会根据当时的语法去判断是否是方程或变量.
  • 起始 (a fresh start): 函数每次运行, 其中的变量都是重新建立的, 和上次运行没有关系.
  • 动态查找 (dynamic lookup): R 语言中, 对变量的查找是在函数运行的时候进行的, 而不是在建立的时候建立的.

参数解析



R 函数对于参数的解析是很方便的. R 函数的参数可以按照顺序进行分配, 也可以通过参数名称进行指定. 所有的参数会把直接通过参数名赋值的参数进行对应赋值, 然后剩下的没有通过参数名赋值的, 按照顺序排列, 通过按顺序赋值的方式进行赋值
  1. myfunc <- function(a, b, c) {
  2.     print(a)
  3.     print(b)
  4.     print(c)
  5. }
  6. myfunc1(1, 2, b = 3)
  7. #[1] 1
  8. #[1] 3
  9. #[1] 2
复制代码
R 函数还可以指定默认值. 直接在参数表中加上等号来设置默认参数. 需要注意的是, 有默认值的参数也会按照顺序进行赋值, 并不会跳过有默认值的参数.

  1. myfunc2 <- function(a, b = 3) {
  2.     print(a)
  3.     print(b)
  4. }
  5. myfunc2(1)
  6. #[1] 1
  7. #[1] 3
复制代码
可以通过 missing() 函数来判断某个参数是否缺失.



  1. myfunc3 <- function(a, b) {
  2.     c(missing(a), missing(b))
  3. }
  4. myfunc3(b = 1)
  5. #[1]  TRUE FALSE
复制代码

另外只有用到的参数才会实际上解析, 没有用到的参数就不会解析, 这样也不会耗费时间. 如果强制对某个没有用到的参数进行解析, 可以使用 force 函数.
需要提及的是 ... 参数. 这个参数可以匹配任何没有被匹配的参数, 并可以方便地传递到其他函数. 但是这个参数并不会去验证正确性, 所以即是有打字错误, 外部函数并不会报错.
  1. myfunc4 <- function(...) {
  2.     names(list(...))
  3. }
  4. myfunc4(a = 1, b = 2)
  5. #[1] "a" "b"
复制代码
返回函数


如果没有使用 return 函数去指定函数的返回值, 则默认返回函数体中最后一条执行的命令的结果. 尽管函数只能返回一个结果, 但这个结果可以是一个数值, 可以是一个列表, 也可以是一个函数, 所以实际上一个函数可以返回符合需要的值.
如果不希望返回值被打印, 可以使用 invisable 函数. invisable 的结果可以被赋值, 但不会打印在屏幕, 不过总可以通过把其值包含在小括号中来打印出来.



  1. (invisable(2))
  2. #[1] 2
  3. (a <- 2)
  4. #[1] 2
复制代码

on.exit 函数可以设置当一个函数结束时采取什么动作. 其中可以是改变工作区间, 也可以删除临时变量等.

特殊函数


R 语言中有两类特殊函数: 中置函数 (infix function), 替换函数 (replacement function).

中置函数


经常用到的很多函数都是前置的, 就是一个函数名, 然后后面是括号和括号里面的参数. 有一些函数是中置的. R 中内部定义了一些: ::, $, @, ˆ, *, /, +, -, >, >=, <, <=, ==, !=, !, &, &&, |, ||, ~, <-, <<-. 自己定义的中置函数需要在前后加上百分号, 如一些已经定义好的函数: %%, %*%, %/%, %in%, %o%, %x%. 这些中置函数也可以像前置函数那样使用, 不过需使用引号来标明函数名.
  1. "%+%" <- function(a, b) paste(a, b, sep = "")
  2. "new" %+% "string"
  3. #[1] "newstring"
  4. `%+%`("new", " string")
  5. #[1] "newstring"
复制代码

替换函数

替换函数有着特殊的名称形式 `xxx<-`, 可以直接对内容进行替换. 常见的如 dim, names 等函数. 替换函数, 看上去是对变量内容的直接替换, 实际上在 R 里面是新建了一个变量, 所以效率依然是不高的.

回复

使用道具 举报

北京大学生物信息平台论坛

GMT+8, 2017-9-20 04:45 , Processed in 0.039073 second(s), 23 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表