概述
循环在处理数据的时候非常重要,但不得不说写function的时候还是得绕不少弯路,好在现在R语言有非常多函数可以直接使用,带来不少便利。在学习写looping function 的时候,可以先熟练掌握了以下向量化操作apply、tapply、lapply、sapply、mapply的函数,然后再自己尝试写自己的:
lapply | lapply(X,FUN,...) ,注意:若X不是列表,但会被强制as.list |
sapply | sapply(X, FUN,..., simplify = TRUE, USE.NAMES = TRUE) ;与Lapply相似,或者说是lapply的衍生 |
apply | apply(X, MARGIN, FUN, ...),把FUN用到array的特定margins |
tapply | tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE),专门用来处理分组数据的 |
mapply | mapply(FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE,USE.NAMES = TRUE) ,mapply是sapply的变形 |
#下面使用R自带的数据来实践:
> library(datasets)
> data(iris)
#在使用这个iris之前,建议大家可以先看看这个数据的具体情况
> ?iris
lapply:
lapply(list, function)
function (X, FUN, ...)
{
FUN <- match.fun(FUN)
if (!is.vector(X) || is.object(X))
X <- as.list(X)
.Internal(lapply(X, FUN))
}
<bytecode: 0x000000000263dea8>
<environment: namespace:base>
lapply的返回值是和一个和X有相同的长度的list对象,这个list对象中的每个元素是将函数FUN应用到X的每一个元素。其中X为List对象(该list的每个元素都是一个向量),其他类型的对象会被R通过函数as.list()自动转换为list类型。
lappy()的处理对象是向量、列表或其它对象,它将向量中的每个元素作为参数,输入到处理函数中,最后生成结果的格式为列表。在R中数据框是一种特殊的列表,所以数据框的列也将作为函数的处理对象。
试一下lapply来求'Sepal.Length'的平均值(mean)
lapply(iris, mean)
返回的是
$Sepal.Length
[1] 5.843333
$Sepal.Width
[1] 3.057333
$Petal.Length
[1] 3.758
$Petal.Width
[1] 1.199333
$Species
[1] NA
sapply
> sapply
function (X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE)
{
FUN <- match.fun(FUN)
answer <- lapply(X = X, FUN = FUN, ...)
if (USE.NAMES && is.character(X) && is.null(names(answer)))
names(answer) <- X
if (!identical(simplify, FALSE) && length(answer))
simplify2array(answer, higher = (simplify == "array"))
else answer
}
<bytecode: 0x0000000015568688>
<environment: namespace:base>
sapply和lapply返回值是一样的。但参数simplify=T,其返回值就不是list,而是matrix;相反,simplify=F,其返回值还是list。
仍用求iris每个量的mean来看一下区别:
> sapply(iris,mean)
Sepal.Length Sepal.Width
5.843333 3.057333
Petal.Length Petal.Width
3.758000 1.199333
Species
NA
> sapply(iris,mean,simplify = F)
$Sepal.Length
[1] 5.843333
$Sepal.Width
[1] 3.057333
$Petal.Length
[1] 3.758
$Petal.Width
[1] 1.199333
$Species
[1] NA
apply
> apply
function (X, MARGIN, FUN, ...)
其中X是array;MARGIN是向量(表示要将函数FUN应用到X的行还是列),若为1表示取行,为2表示取列,为c(1,2)表示行、列都计算。apply()函数的处理对象是矩阵或数组,它逐行或逐列的处理数据,其输出的结果将是一个向量或是矩阵。下面的例子即对一个随机矩阵求每一行的均值。要注意的是apply与其它函数不同,它并不能明显改善计算效率,因为它本身内置为循环运算。
为了方便理解 ,举个函数的例子:
rowSums = apply(x, 1, sum)
rowMeans = apply(x, 1, mean)
colSums = apply(x, 2, sum)
colMeans = apply(x, 2, mean)
或者大家可以直接使用iris3来尝试一下不同的结果:
tapply
> tapply
function (X, INDEX, FUN = NULL, ..., default = NA, simplify = TRUE)
用于分组统计(index)
其中X通常是一向量;INDEX是一个list对象,且该list中的每一个元素都是与X有同样长度的因子;FUN是需要计算的函数;simplify是逻辑变量,若取值为TRUE(默认值),且函数FUN的计算结果总是为一个标量值,那么函数tapply返回一个数组;若取值为FALSE,则函数tapply的返回值为一个list对象。需要注意的是,当第二个参数INDEX不是因子时,函数 tapply() 同样有效,因为必要时 R 会用 as.factor()把参数强制转换成因子。
tapply()的功能则又有不同,它是专门用来处理分组数据的,其参数要比sapply多一个。我们以iris数据集为例,可观察到Species列中存放了三种花的名称,我们的目的是要计算三种花瓣萼片宽度的均值。其输出结果是数组格式。
> tapply(1:17, fac, sum)
1 2 3 4 5
51 57 45 NA NA
> tapply(1:17, fac, sum, simplify = FALSE)
$`1`
[1] 51
$`2`
[1] 57
$`3`
[1] 45
$`4`
NULL
$`5`
NULL
> tapply(1:17, fac, range)
$`1`
[1] 1 16
$`2`
[1] 2 17
$`3`
[1] 3 15
$`4`
NULL
$`5`
NULL
更多的练习可以参照:R Programming Week 3 Quiz & Ans
最后
以上就是闪闪便当为你收集整理的R语言实现循环loop的函数解读(带练习)的全部内容,希望文章能够帮你解决R语言实现循环loop的函数解读(带练习)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复