跳转到内容

R 编程/函数的使用

来自维基教科书,自由的教科书,打造自由的世界

查看函数的代码

[编辑 | 编辑源代码]
  • 您可以在控制台中输入函数名称,函数名称后面不带括号。这将在控制台中打印函数的代码。
  • 您也可以使用page()函数,它将打开一个新的编辑器窗口并在该编辑器中打印函数的代码。
  • 您也可以使用TinnR包中的trCopy()函数来复制函数的代码。然后您只需将其粘贴到文本编辑器中即可查看它。

以下是使用lm()函数的示例。

> lm
> page(lm)
> library(TinnR)
> trCopy(lm)

创建您自己的函数

[编辑 | 编辑源代码]

一个没有参数且不返回值的简单函数

[编辑 | 编辑源代码]
> fn <- function(){
+ print("hello")
+ }
> fn()
[1] "hello"


返回值

[编辑 | 编辑源代码]

默认情况下,将返回最后一行(*)的值。在下面的示例中,我们有一个包含两个对象的简单函数。返回最后一个对象。

> test <- function() {
+ x <-1
+ z <- 2
+ }
> res <- test()
> res
[1] 2

函数可以使用以下方法显式返回值return()(但由于它是最后一行,您可以简单地使用x代替)

> test <- function() {
+ x <- 1
+ z <- 2
+ return(x)
+ }
> res <- test()
> res
[1] 1
  • ) 更准确地说,它不是“最后一行”,而是最后一次计算的值从函数返回。

添加参数

[编辑 | 编辑源代码]

可以添加参数。

square <- function(x){
	x2 <- x^2
	return(x2)
	}
square(x = 2)

请注意,上面的函数最好写成(更有效率)

square <- function(x) x^2

(因为最后的值会被返回)

... 参数意味着您可以添加其他参数,这些参数将传递给函数内部的函数。

plot2 <- function(x,...){
	plot(x, type = "l", ...)
	}
plot2(runif(100), main = "line plot", col = "red")

可以将数据框添加为参数[1]。以下是一个示例

redplot <- function(z, y, data, env=parent.frame()) {
       if(!missing(data)){
			z <- data[,deparse(substitute(z))]
			y <- data[,deparse(substitute(y))]
			}
	plot(z,y, col = "red", pch = 15)
} 

mydat <- data.frame(vm = rnorm(10),output = rnorm(10))
redplot(vm,output,data=mydat)

对于估计命令,可以将公式添加为参数。例如,我们可以使用公式接口创建自己的普通最小二乘函数。

ols <- function(formula, data = list()) {
	mf <- model.frame(formula=formula, data=data)
	X <- model.matrix(attr(mf, "terms"), data=mf)
	y <- model.response(mf)
	beta <- solve(t(X)%*%X)%*%t(X)%*%y
	se <- sqrt( 1/(nrow(X) - ncol(X)) * sum((y - X%*%beta)^2) * diag(solve(t(X)%*%X)))
	res <- cbind(beta,se)
	colnames(res) <- c("Coefficients","Standard errors")
	res
}
N <- 100
u <- rnorm(N)
x <- rnorm(N) + 1
y <- 1 + x + u
ols(y~x)

递归函数

[编辑 | 编辑源代码]

R 支持递归函数。下面的函数递归地计算斐波那契数

> fib <- function(n) {
              if(n > 2) {
                   m <- fib(n-1)
                   c(m, sum(tail(m, 2)))
                   }
              else rep(1, n)
              }
> fib(30)
 [1]      1      1      2      3      5      8     13     21     34     55
[11]     89    144    233    377    610    987   1597   2584   4181   6765
[21]  10946  17711  28657  46368  75025 121393 196418 317811 514229 832040

函数作为对象

[编辑 | 编辑源代码]

R 函数可以被视为对象

> a <- function(n) function(a) runif(a)
> b <- a(1)
> b(10)
 [1] 0.8726873 0.9512367 0.5971435 0.5540743 0.6378967 0.4030071 0.2750673 0.1777123 0.6960378 0.3969920

当想要创建许多不同类型的函数时,这将非常有用

> a <- list()
> b <- function(i){ i; function() runif(i)}
> for (i in 1:10) a[[i]] <- b(i)
> a[[1]]()
[1] 0.2617396
> a[[2]]()
[1] 0.8822248 0.3374574
> a[[3]]()
[1] 0.0348156 0.4212788 0.6107646

高阶函数

[编辑 | 编辑源代码]

您可以在R中使用高阶函数。与普遍看法相反,使用它们而不是循环并不更快,因为 apply 函数在其定义内部有一个 for 循环。仅在需要提高代码清晰度时使用它们。[2]

apply 是 R 的映射函数中最基本的一个。lapply、sapply 和 mapply 是 apply 的方便接口,分别用于列表、向量和多个向量。

apply 以数组、要映射的维度的向量和函数作为参数。以下示例基于 apply 文档。它使用 apply 计算矩阵的列和行总和。

x <- matrix(round(rnorm(100)),10,10)
col.sums <- apply(x, 2, sum)
row.sums <- apply(x, 1, sum)


tapply 与 apply 相似,但它将函数应用于不规则数组的每个单元格,即应用于由某些因子的级别唯一组合给出的每个(非空)值组。

> x1 <- rnorm(10)
> x2 <- sample(1:2, 10, replace = T)
> cbind(x1,x2)
              x1 x2
 [1,] -1.7905021  1
 [2,]  1.2908169  2
 [3,] -2.1902513  2
 [4,]  0.4845488  1
 [5,]  0.2281593  1
 [6,]  0.2201302  1
 [7,]  2.1574243  1
 [8,]  0.5789705  2
 [9,]  1.3315188  1
[10,] -1.0029822  2
> tapply(x1, x2, sum)
        1         2 
 2.631279 -1.323446

Reduce 文档中的此函数累加地添加

> cadd <- function(x) Reduce("+", x, accumulate = TRUE)
> cadd(1:10)
 [1]  1  3  6 10 15 21 28 36 45 55

参考文献

[编辑 | 编辑源代码]
华夏公益教科书