R语言向量化运算之apply函数族+split+by

apply函数族包括apply(),lapply(),sapply(),vapply(),mapply(),rapply(),tapply(),在实际应用中需要依据不同数据结构和数据处理目的采用不同的函数,apply函数族的向量化运算是基于C语言实现的

1.apply函数

apply(x,margin,fun,...)   
#可以将任意一个函数应用到数组或矩阵(所有数据必须同一类型)的任何维度上,...包含了任何能传递到fun的参数,margin=1表示行,margin=2表示列,margin=c(1,2)表示同时以行和列为单位进行计算,返回向量或矩阵
apply(tian,2,mean,trim=0.2)  #计算每列的截尾均值

2.lapply和sapply函数

两个函数都可用于处理list\vector\array\matrix\data.frame类型数据,但lapply()返回list数据类型,其他方面两者基本一致

lapply(x,fun,...)
sapply(x,fun,...,simplify=T,USE.NAMES=T)
#simplify逻辑值或者字符,T返回向量或矩阵(F-list),simplify="array"返回数组,USE.NAMES确定返回结果名称(只对x是向量时起作用)

A<-matrix(c(1:9), nrow=3, ncol=3)
B<-matrix(c(4:15), nrow=4, ncol=3)
C<-matrix(rep(seq(8,10),2), nrow=3)
data<-list(A=A, B=B, C=C)	#创建数据集
lapply(A,sum)	#对矩阵A的每个值进行求和(相当于将A转为向量,逐个求和)
lapply(data, "[", ,2)	#提取列表中每一部分第二列的元素
lapply(data, "[", 1,)	#提取列表中每一部分第一行的元素
lapply(data, sum)	#对列表每一部分求和

sapply(data, "[", 2, 1)	#提取列表每一部分第二行第一列的数,并以向量形式返回
sapply(data, "[", 2, 1, simplify=F)#提取列表每一部分第二行第一列的数,并以列表形式返回

dat_vec <- c('tian', 'shan', 'zhienng')
sapply(dat_vec, nchar)
sapply(dat_vec, nchar, USE.NAMES = F)	#不返回名称

3.vapply函数

vapply(X,FUN,FUN.VALUE,...,USE.NAMES=TRUE)
#X-向量/列表/数组/数据框,FUN.VALUE-设置行索引,USE.NAMES是否返回名称
#vapply和sapply函数的区别在于,前者可控制行名
dat_vec<-c('tian', 'shan', 'zhienng')
#计算向量中字符串的长度
vapply(dat_vec,nchar,FUN.VALUE=c('a'= 0),USE.NAMES=F)	#FUN.VALUE值的length要与函数返回值的行数一致(类型也要一致)

4.mapply函数

mapply(FUN,...,MoreArgs=NULL,SIMPLIFY=TRUE,USE.NAMES=TRUE)
#FUN-自定义函数,...FUN的参数,MoreArgs-函数的其他参数列表,SIMPLIFY-自定义返回类型(数组,矩阵或列表),输入-vector不限个数,返回vector或matrix
mapply(rep,1:4,each=2)
mapply(function(x,y) nchar(x)*y,c('wu','xiang','ni'),c(1:3),USE.NAMES=F)

5.tapply函数

tapply(x,INDEX,FUN=NULL,...,simplify=T)
#x-向量,INDEX-种类(每个因子需要与x具有相同的长度),返回向量
#构建数据框-成绩统计
dat_df2<-data.frame(class = sample(1:3,100,replace=T),gender=sample(c('f','m'),100,replace=T),score=sample(60:95,100,replace=T))
#统计不同班级、不同性别的学生的平均分
tapply(dat_df2$score,INDEX=list(dat_df2$class,dat_df2$gender),mean)

6.rapply函数

rapply可理解为递归版本的lapply,只处理list类型(对list中的每一个元素进行递归遍历,如果list元素中还包括子元素需要继续遍历)

rapply(x,FUN,classes=ANY,deflt=NULL,how=c(unlist,replace,list),...)
#x-list对象,classes-关于类名的字符向量(any表示任何类型),how-字符串匹配的3种结果,
deflt-默认结果(不能用于how='replace')
#how='replace':将x-list元素中的值替换为FUN应用元素后的结果,how=list:将x-list元素中符合classes的类替换为FUN应用元素后的结果,其他替换为deflt的值

X <- list(list(a = pi, b = list(c = 1:1)), d = "a test")
rapply(X, function(x) x, how = "replace")	#返回自身
rapply(X, sqrt, classes = "numeric", how = "replace")
rapply(X, nchar, classes = "character", deflt = as.integer(NA), how = "list")
rapply(X, nchar, classes = "character", deflt = as.integer(NA), how = "unlist")
rapply(X, nchar, classes = "character", how = "unlist")
rapply(X, nchar, classes = "character", deflt = 2 ,how = "unlist")
rapply(X, log, classes = "numeric", how = "replace", base = 2)

7.eapply函数

eapply函数可遍历R当前环境空间中的每个变量

eapply(env,FUN,...,all.names=FLASE,USE.NAMES=TRUE)
#env-定义好的R环境空间,all.names-逻辑值,是否对所有值使用函数,USE.NAMES-控制返回值行名,返回list

env<-new.env(hash = FALSE)	#定义一个环境空间
#向这个环境空间中存入3个变量
env$a<-5:15
env$beta<-exp(3:8)
env$logic<-c(TRUE, FALSE, FALSE, TRUE)
#查看env空间中的变量
ls(env)
[1] "a"    "beta"  "logic"
ls.str(env)
a :  int [1:11] 5 6 7 8 9 10 11 12 13 14 ...
beta :  num [1:6] 20.1 54.6 148.4 403.4 1096.6 ...
logic :  logi [1:4] TRUE FALSE FALSE TRUE
#对环境空间内所有对象遍历计算均值
eapply(env, mean)
$logic
[1] 0.5
$beta
[1] 784.0195
$a
[1] 10

8.split函数

split(x,f)-只形成分组,x是向量或者数据框data.frame,f是因子或因子列表,并返回分组列表list

n <- 10; nn <- 100
g <- factor(round(n * runif(n * nn)))
x <- rnorm(n * nn) + sqrt(as.numeric(g))
xg <- split(x, g)	#返回11个list

9.by函数

by函数与tapply函数的运作机制是相同的,但by()的应用对象不仅是向量,也包括矩阵和数据框

aba<-read.csv(“abalone.data”,header=TRUE);
by(aba,aba$Gender,function(m) lm(m[,2]~m[,3]));

 

猜你喜欢

转载自blog.csdn.net/qq_38984677/article/details/81676556