R语言 函数类型
一个函数是一组协调在一起的语句,以执行一个特定的操作。一个函数是一个对象,因此解释器能够将控制权以及函数完成操作所需的参数传递给函数。该函数反过来执行任务,并将控制权返回给解释器,以及任何可能存储在其他对象中的返回值。
如何定义一个函数
在R编程中,可以使用关键字function来定义一个函数。在R语言中定义一个函数的语法如下:
语法
function_name = function(arg_1, arg_2, ...)
{
Function body
}
一个函数的各个组成部分/部分是:
- 函数名: 它是函数的实际名称。它在R环境中作为一个对象,以这个名字存储。
- 参数: 一个参数是一个占位符。每当一个函数被调用时,一个值会被传递给参数。它们是可选的;也就是说,一个函数可以不包含参数。同时,参数可以有默认值。
- 函数主体: 它包含所有的语句集,定义了函数的实际操作。
- 返回值: 它是函数在成功执行任务后返回的值。一般来说,它是函数主体中最后被评估的表达式。
调用一个函数
它只不过是用有效的参数数来调用原始函数。一个函数可以带参数调用,也可以不带参数调用,还可以带默认值调用。
例子: 调用一个没有参数的函数
# create a function cube
# without an argument
cube <- function()
{
for(i in 1:10)
{
print(i^3)
}
}
# calling function cube without an argument
cube()
输出
[1] 1
[1] 8
[1] 27
[1] 64
[1] 125
[1] 216
[1] 343
[1] 512
[1] 729
[1] 1000
例子: 用一个参数调用一个函数。
# create a function factorial
# with a numeric argument n
factorial <- function(n)
{
if(n==0)
{
return(1)
}
else
{
return(n * factorial(n - 2))
}
}
# calling function cube with an argument
factorial(7)
输出
[1] 5040
例子: 调用一个带有默认参数的函数。
# create a function def_arg
# without an argument
def_arg <- function(a = 23, b = 35)
{
output <- (a + b) * a + (a - b) * b
print(output)
}
# calling function def_arg without an argument
def_arg()
# call the function with giving new values of the argument.
def_arg(16, 22)
输出
[1] 914
[1] 476
函数的类型
R编程中主要有三种类型的函数:
- 原始函数
- 嵌套函数
- 替换函数
原始函数
一般来说,一个函数由三部分组成:
- formals() , 控制你如何调用该函数的参数列表。
- body() , 函数中的代码。
- environment() , 数据结构,决定了函数如何找到与名称相关的值。
每当创建一个函数时,formals和body都是显式定义的,但环境是隐式指定的,基于你定义函数的位置。但是,一个函数有三个组成部分的规则有一个例外,一些函数直接调用C代码。这些函数被称为原始函数。原始函数主要存在于C语言中,而不是R语言,所以它们的 formals() , body() ,和 environment() 都是空的。这些函数只存在于基础包中。原始函数比较难写,但效率很高。它们有两种类型,要么是内置类型,要么是特殊类型。
typeof(sum)
typeof('[')
[1] "builtin" #> typeof(sum)
[1] "character" #> typeof('[')
例子: 要在R控制台打印可用的原始函数的名称,请运行以下代码。
names(methods:::.BasicFunsList)
输出
[1] "" "<-" "[" "[<-" "[[" "[[=" "cosh" "cummax" "dimnames<-"
[22] "as.raw" "log2" "tan" "dim" "as.logical" "^" "is.finite"
[29] "sinh" "log10" "as.numeric" "dim<-" "is.array" "tanpi" "gamma"
[36] "atan" "as.integer" "Arg" "signif" "cumprod" "cos" "length"
[43] "!=" "digamma" "exp" "floor" "acos" "seq.int" "abs"
[50] "length<-" "sqrt" "!" "acosh" "is.nan" "Re" "tanh"
[57] "names" "cospi" "&" "anyNA" "trunc" "cummin" "levels<-"
[64] "*" "Mod" "|" "names<-" "+" "log" "lgamma"
[71] "as.complex" "asinh" "-" "sin" "/" "as.environment" "<="
[78] "as.double" "is.infinite" "is.numeric" "rep" "round" "sinpi" "dimnames"
[85] "asin" "as.character" "%/%" "is.na" "" "Im"
[92] "%%" "trigamma" "==" "cumsum" "atanh" "sign" "ceiling"
[99] "Conj" "as.call" "log1p" "expm1" "(" ":" "="
[106] "@" "{" "~" "&&" ".C" "baseenv" "quote"
[113] "<-" "is.name" "if" "||" "attr<-" "untracemem" ".cache_class"
[120] "substitute" "interactive" "is.call" "switch" "function" "is.single" "is.null"
[127] "is.language" "is.pairlist" ".External.graphics" "globalenv" "class<-" ".Primitive" "is.logical"
[134] "enc2utf8" "UseMethod" ".subset" "proc.time" "enc2native" "repeat" "<<-"
[141] "@<-" "missing" "nargs" "isS4" ".isMethodsDispatchOn" "forceAndCall" ".primTrace"
[148] "storage.mode<-" ".Call" "unclass" "gc.time" ".subset2" "environment<-" "emptyenv"
[155] "seq_len" ".External2" "is.symbol" "class" "on.exit" "is.raw" "for"
[162] "is.complex" "list" "invisible" "is.character" "oldClass<-" "is.environment" "attributes"
[169] "break" "return" "attr" "tracemem" "next" ".Call.graphics" "standardGeneric"
[176] "is.atomic" "retracemem" "expression" "is.expression" "call" "is.object" "pos.to.env"
[183] "attributes<-" ".primUntrace" "...length" ".External" "oldClass" ".Internal" ".Fortran"
[190] "browser" "is.double" ".class2" "while" "nzchar" "is.list" "lazyLoadDBfetch"
[197] "...elt" "is.integer" "is.function" "is.recursive" "seq_along" "unlist" "as.vector"
[204] "lengths"
隐式函数
Infix函数是指那些函数名称位于其参数之间的函数,因此有两个参数。R有许多内置的infix运算符,如 :, :, ::, $, @, ^, *, /, +, -, >, >=, <, <=, ==, !=, !, &, &&, |, ||, ~, <-, and <<- .
人们可以创建自己的以%开头和结尾的infix函数。一个infix函数的名称更加灵活,因为它可以包含除%以外的任何字符序列。在R编程中,有一些预定义的infix运算符。
运算符 | 说明 |
---|---|
%% | 余数运算符 |
%/% | 整数除法 |
%*% |
矩阵乘法 |
%o% | 外积 |
%x% | 克朗克乘积 |
%in% | 匹配运算符 |
例子: 创建一个两个参数的函数,给出两个数字的大数,并将其绑定到一个以%开头和结尾的名称。
# R program to illustrate
# Infix function
'%Greater%' <- function(a, b)
{
if(a > b) print(a)
else if(b > a) print(b)
else print("equal")
}
5 %Greater% 7
2300 %Greater% 67
输出
[1] 7
[1] 2300
替换函数
替换函数在原地修改他们的参数(修改一个R对象通常会创建一个副本)。替换函数的名称总是以<为继。它们必须有名为x和value的参数,并返回修改后的对象。在替换的情况下,一个函数需要额外的参数,额外的参数应该放在x和value之间,并且必须用左边的额外参数调用。函数的名称必须加引号,因为它是一个语法上有效但非标准的名称,如果不加引号,解析器会把<-
解释为操作符而不是函数名称的一部分。
语法
"function_name<-" <- function(x, additional arguments, value)
{
function body
}
例子
# R program to illustrate
# Replacement function
"replace<-" <- function(x, value)
{
x[1] = value
x
}
x = rep.int(5, 7)
replace(x) = 0L
print(x)
输出
[1] 0 5 5 5 5 5 5