apply函数对行/列运算

apply(X,MARGIN,FUN,...) 对矩阵、数据库、数组按行或列进行迭代计算,返回向量或数组或值列表。 apply系列函数有效替代R中比较慢的for循环。

X: 输入的数组、矩阵,如果是数据框会自动转换成矩阵

MARGIN:按行计算或按列计算,1表示按行,2表示按列。

FUN:调用的函数

...: 可选项,为函数FUN提供额外参数。即如果一个函数有多个参数,那么...就是传入除第一个参数意外的其他参数。

 

例子:

df<-data.frame(x=c("A","B","C","A","C"),'2010'=c(1,3,4,4,3),'2011'=c(3,5,2,8,9),check.names=FALSE)

df_rowsum<-apply(df[,2:3],1,sum) #对2、3列,采用按行计算。

df_colsum<-apply(df[,2:3],2,sum) # 采用按列计算

 

 

给apply的调用函数传参的情形如apply(counts,2,max,na.rm=TRUE)

 

 > sapply(X,FUN,...,simplify=TRUE,USE.NAMES=TRUE)

 X 向量

FUN 调用函数

simplify 是否简化输出格式

例子: sapply(iris, mean) # 出现 Warining,是因为Species不是数值列。 

 

 解决方案是判断列的数据类型 sapply(iris, function(x) ifelse(is.numeric(x),mean(x),NA))  # function(x) ifelse(is.numeric(x),mean(x),NA) 是匿名函数

 

 例子2. 对数据框的每列计算

> clients <- data.frame(  hours = c(20, 120, 120, 23), +public = c(TRUE, TRUE,TRUE, TRUE))

> sapply(clients,unique)

 

 

 

 

》 lapply 中l表示list(列表). sapply()是lapply的simplify简化方式。

 lapply(X,FUN,...) , 作用对象x是list列表,  返回值也是list列表

 例1   lapply(x,mean)   注:x是列表

    

 

 

例2  sapply是lapply的简化格式   

 

 

 

 例3 再次说明apply做的事是代替for循环。如

   测试数据集

 

  lapply 写法  > lapply(prime_factors,unique)

  for循环写法      for (i in seq_along(prime_factors)) 

        {unique_primes[[i]]<-unique(prime_factors[[i]])}

         names(unique_primes)<-names(prime_factors)

        unique_primes

两个写法效果一样

  

 

 

  例4。lapply 调用函数传不同数量的参数

  4.1 函数定义第一个参数是向量,第二个参数是标量。此时可以直接作为参数传入。如 rep(c(1,2,3,4),times=5) 这种的,可以> lapply(complemented,rep,times=4)

  

 

 

 

     4.2 更泛适合的是定义一个函数封装一下,如rep4x<-function(x) rep(4,times=x),再lapply(complemented,rep4x),

    还可以写匿名函数来较简单的实现如lapply(complemented,function(x) rep(4,times=x))

  

 

》vapply 应用于列表返回向量vector,输入参数: 列表,调用函数,返回值模版. 如 vapply(prime_factors,length,numeric(1)) 感觉不如 sapply(prime_factors,length) 简练

 

 

 》tapply()函数 常用于处理因子类型数据,t指table. 逻辑如下:

  1. 将数据成组,每组对应一个因子水平(或在多重因子的情况下对应一组因子水平的组合)

  2. 对每组数据 调用函数

 例子1: tapply(iris$Sepal.Length,iris$Species,mean)  # 把iris$Sepal.Length 按iris$Species分组,然后计算每组的平均值

   

 

  例2: with(cars,tapply(mpg,list(gear,am),mean)) 

     

 

 

 》by()函数 类似tapply, 但by()可以应用于矩阵或数据框,而tapply只能用于向量(第一个参数)。

 by()函数,输入参数: 数据集,分组因子,调用函数 . 如 > by(iris,iris$Species,function(m) lm(m[,1]~m[,2]))

 

 

》aggregate()函数对分组中的每个变量应用tapply()函数,如aggregate(CO2[,c(4,5)],list(CO2$Treatment),median)

 

 

 

 

 

 

 

 

备注: switch(expr,list)  。如果expr计算结果为整数,且值在1~length(list)之间,则switch函数返回列表对应位置的值,否则没返回值或返回NULL

  expr是表达式,值为整数值或字符串

  list 列表  

  如果switch返回字符串,则查找相应变量如> switch("c",a="weizhi1",b="weizhi2",c="weizhi3")

  

 

  

 

更多的apply函数家族参考:http://showteeth.tech/posts/15576.html

 

 

对数据框分组计算,用aggregate函数,~左边表示待操作变量,~右边表示依据。注:依据可以是一个或多个。

例子:

 df_melt<-reshape2::melt(df,id.var="x",variable.name="year",value.name="value")

 > da_group1<-aggregate(value~year,df_melt,mean) # 数据框df_melt,按year对变量value执行mean计算。

 

 

 

 

 

 ~右边是多个时,则是右边这些变量不同组合情况下的函数操作。

如:> df_group2<-aggregate(value~year+x,df_melt,mean)

 

 

 ~ 左边是多个变量,表示待操作的是多个变量,这些变量分别依据~右侧变量进行函数操作。

如> df_group3<-aggregate(cbind(value,year)~x,df_melt,mean)

 

 

 对数据框分组计算与aggregate类似但更灵活的是通过dplyr包的groupby()分组,summarise()分组的汇总运算,arrange()分组的变量排序等组合实现与aggregate()类似功能。

常需要搭配%>%这个多步操作连接符。注:groupyby()常和summarise()搭配使用,后者需要前者分组功能。

例子:

> df_groupmean1<-df_melt%>%dplyr::group_by(year)%>% + dplyr::summarise(avg=mean(value)) #与aggregate(value~year,df_melt,mean)效果一致。

> df_groupmean2<-df_melt%>%dplyr::group_by(year,x)%>%dplyr::summarise(avg=mean(value))#与aggregate(value~year+x,df_melt,mean)效果一致。

 

 

posted on 2021-10-01 16:07  BioinformaticsMaster  阅读(815)  评论(0编辑  收藏  举报

导航