• 主页
  • 课程

    关于课程

    • 课程归档
    • 成为一名讲师
    • 讲师信息
    同等学历教学

    同等学历教学

    免费
    阅读更多
  • 特色
    • 展示
    • 关于我们
    • 问答
  • 事件
  • 个性化
  • 博客
  • 联系
  • 站点资源
    有任何问题吗?
    (00) 123 456 789
    weinfoadmin@weinformatics.cn
    注册登录
    恒诺新知
    • 主页
    • 课程

      关于课程

      • 课程归档
      • 成为一名讲师
      • 讲师信息
      同等学历教学

      同等学历教学

      免费
      阅读更多
    • 特色
      • 展示
      • 关于我们
      • 问答
    • 事件
    • 个性化
    • 博客
    • 联系
    • 站点资源

      R语言

      • 首页
      • 博客
      • R语言
      • 【R知识】R语言apply函数族笔记

      【R知识】R语言apply函数族笔记

      • 发布者 weinfoadmin
      • 分类 R语言
      • 日期 2016年3月10日
      测试开头

      为什么用apply

      因为我是一个程序员,所以在最初学习R的时候,当成“又一门编程语言”来学习,但是怎么学都觉得别扭。现在我的看法倾向于,R不是一种通用型的编程语言,而是一种统计领域的软件工具。因此,不能用通用型编程的思维来设计R代码。在    Andrew Lim 关于R和Python的对比回答中,R是一种面向数组(array-oriented)的语法,它更像数学,方便科学家将数学公式转化为R代码。而Python是一种通用编程语言,更工程化。在使用R时,要尽量用array的方式思考,避免for循环。不用循环怎么实现迭代呢?这就需要用到    apply 函数族。它不是一个函数,而是一族功能类似的函数。

      概述

      apply系列函数的基本作用是对数组(array,可以是多维)或者列表(list)按照元素或元素构成的子集合进行迭代,并将当前元素或子集合作为参数调用某个指定函数。vector是一维的array,dataframe可以看作特殊的list。

      这些函数间的关系

      作用目标 在每个元素上应用 在子集合上应用
      array apply         tapply        
      list lapply (…) by        

      其中    lapply(...) 包括一族函数

      lapply    |    |-> 简化版: sapply    |             | -> 可设置返回值模板: vapply    |             |-> 多变量版: mapply    |    |-> 递归版: rapply

      另外vector比较奇怪,vector是一维的array,但是却不全是和array使用相同的函数。在按元素迭代的情况下,使用和list一样的    lapply 函数;而在按子集合迭代的情况下,    tapply 和    by 都能用,只是返回值形式不同。

      功能与语法描述

      apply

      apply(array, margin, FUN, ...)

      在array上,沿margin方向,依次调用    FUN 。返回值为vector。margin表示数组引用的第几维下标(即array[index1, index2, …]中的第几个index),1对应为1表示行,2表示列,c(1,2)表示行列。margin=1时,    apply(a, 1, sum) 等效于下面的操作

      a <- array(c(1:24), dim=c(2,3,4))result=c()for (i in c(1:dim(a)[1])) {    result <- c(result, sum(a[i,,])) }

      经实测,只能用在二维及以上的array上,不能用在vector上(如果要应用于vector,请使用    lapply 或    sapply )。以matrix为例,如下

      > m <- matrix(c(1:10), nrow=2)> m  [,1] [,2] [,3] [,4] [,5] [1,]    1    3    5    7    9 [2,]    2    4    6    8   10 > apply(m, 1, sum) [1] 25 30 > apply(m, 2, sum) [1]  3  7 11 15 19

      tapply

      tapply(array, indices, margin, FUN=NULL, ...)

      按    indices 中的值分组,把相同值对应下标的array中的元素形成一个集合,应用到    FUN 。类似于group by indices的操作。如果    FUN 返回的是一个值,    tapply 返回vector;若    FUN 返回多个值,    tapply 返回list。vector或list的长度和    indices 中不同值的个数相等。

      当    FUN 为    NULL 的时候,返回一个长度和array中元素个数相等的vector,指示分组的结果,vector中相等的元素所对应的下标属于同一组。例如,返回c(1, 2, 1, 3, 2), 表示根据传入的    indices ,第1、3个元素作为一组,第2、5个元素作为一组,第4个元素作为一组。

      一维array的例子(即vector)

      > v <- c(1:5) > ind <- c('a','a','a','b','b') > tapply(v, ind) [1] 1 1 1 2 2 > tapply(v, ind, sum) a b  6 9  > tapply(v, ind, fivenum) $a [1] 1.0 1.5 2.0 2.5 3.0  $b [1] 4.0 4.0 4.5 5.0 5.0

      二维array的例子(即matrix)

      > m <- matrix(c(1:10), nrow=2)> m      [,1] [,2] [,3] [,4] [,5] [1,]    1    3    5    7    9 [2,]    2    4    6    8   10 > ind <- matrix(c(rep(1,5), rep(2,5)), nrow=2)> ind      [,1] [,2] [,3] [,4] [,5] [1,]    1    1    1    2    2 [2,]    1    1    2    2    2 > tapply(m, ind)  [1] 1 1 1 1 1 2 2 2 2 2 > tapply(m, ind, mean) 1 2  3 8  > tapply(m, ind, fivenum) $`1` [1] 1 2 3 4 5  $`2` [1]  6  7  8  9 10

      by

      by(dataframe, INDICES, FUN, ..., simplify=TRUE)

      by 可以当成dataframe上的    tapply 。    indices 应当和dataframe每列的长度相同。返回值是    by 类型的object。若simplify=FALSE,本质上是个list。

      > df <- data.frame(a=c(1:5), b=c(6:10))> ind <- c(1,1,1,2,2) > res <- by(df, ind, colMeans)  > res ind: 1 a b  2 7  ------------------------------------------------------------  ind: 2   a   b  4.5 9.5  > class(res) [1] "by" > names(res) [1] "1" "2"

      lapply

      lapply(list, FUN, ...)

      在    list 上逐个元素调用    FUN 。可以用于dataframe上,因为dataframe是一种特殊形式的list。例

      > lst <- list(a=c(1:5), b=c(6:10))> lapply(lst, mean) $a [1] 3  $b [1] 8  > lapply(lst, fivenum) $a [1] 1 2 3 4 5  $b [1]  6  7  8  9 10

      sapply

      sapply(list, FUN, ..., simplify, USE.NAME=TRUE)

      比    lapply 多了一个    simplify 参数。如果    simplify=FALSE ,则等价于    lapply 。否则,在上一种情况的基础上,将    lapply 输出的list简化为vector或matrix。例

      > lst <- list(a=c(1:5), b=c(6:10))> sapply(lst, mean) a b  3 8  > sapply(lst, fivenum)  a  b [1,] 1  6 [2,] 2  7 [3,] 3  8 [4,] 4  9 [5,] 5 10

      vapply

      vapply(list, FUN, FUN.VALUE, ..., USE.NAME=TRUE)

      vapply 类似于    sapply ,但是提供了第三个参数    FUN.VALUE 用以指明返回值的形式,可以看作返回值的模板。例

       > lst <- list(a=c(1:5), b=c(6:10))  > res <- vapply(lst, function(x) c(min(x), max(x)), c(min.=0, max.=0))  > res       a  b  min. 1  6  max. 5 10

      mapply

      mapply(FUN, ..., MoreArgs=NULL, SIMPLIFY=TRUE, USE.NAMES=TRUE)

      mapply 是多变量版的    sapply ,参数(…)部分可以接收多个数据,    mapply 将    FUN 应用于这些数据的第一个元素组成的数组,然后是第二个元素组成的数组,以此类推。要求多个数据的长度相同,或者是整数倍关系。返回值是vector或matrix,取决于    FUN 返回值是一个还是多个。

      > mapply(sum, list(a=1,b=2,c=3), list(a=10,b=20,d=30))  a  b  c  11 22 33 > mapply(function(x,y) x^y, c(1:5), c(1:5)) [1]    1    4   27  256 3125> mapply(function(x,y) c(x+y, x^y), c(1:5), c(1:5))      [,1] [,2] [,3] [,4] [,5] [1,]    2    4    6    8   10[2,]    1    4   27  256 3125

      rapply

      rapply(list, FUN, classes="ANY", deflt=NULL, how=c("unlist", "replace", "list"), ...)

      rapply 是递归版的    lappy 。基本原理是对list作遍历,如果其中有的元素仍然是list,则继续遍历;对于每个非list类型的元素,如果其类型是    classes 参数指定的类型之一,则调用    FUN 。classes="ANY"表示匹配所有类型。

      how参数用来指定操作方式,有三种:

      • "replace" 直接用调用      FUN 后的结果替换原list中原来的元素

      • "list" 新建一个list,元素类型在      classes 中的,调用      FUN ;不在      classes 中的类型,使用      deflt 。会保留原始list的结构。

      • "unlist" 相当于对"list"模式下的结果调用      unlist(recursive=TRUE)

       > lst <- list(a=list(aa=c(1:5), ab=c(6:10)), b=list(ba=c(1:10))) > lst$a$a$aa[1] 1 2 3 4 5$a$ab[1]  6  7  8  9 10$b$b$ba  [1]  1  2  3  4  5  6  7  8  9 10> rapply(lst, sum, how='list')$a$a$aa[1] 15$a$ab[1] 40$b$b$ba[1] 55> rapply(lst, sum, how='unlist') a.aa a.ab b.ba    15   40   55 

      第二个是关于    classes 和    deflt 参数使用的例子

      > lst2$a$a$aa[1] 1 2 3 4 5$a$ab[1]  6  7  8  9 10$b$b$ba[1] "I am a string"> rapply(lst2, sum, how='unlist') Error in .Primitive("sum")("I am a string", ...) :    invalid 'type' (character) of argument > rapply(lst2, sum, classes=c('integer'), deflt=-1, how='unlist')a.aa a.ab b.ba    15   40   -1  > rapply(lst2, nchar, classes=c('character'), deflt=as.integer(NA), how='unlist') a.aa a.ab b.ba    NA   NA   13 

      eapply

      environment上的的apply。从没用过environment,暂时不研究了。

      应用

      tapply实现crosstable功能

      以一个例子演示。原始数据为按年份year、地区loc和商品类别type进行统计的销售量。我们要制作两个销售总量的crosstable,一个以年份为行、地区为列,一个以年份为行,类别为列。

      > df <- data.frame(year=kronecker(2001:2003, rep(1,4)), loc=c('beijing','beijing','shanghai','shanghai'), type=rep(c('A','B'),6), sale=rep(1:12))> df  year		loc type sale 1  2001  beijing	 A	 1 2  2001  beijing	 B	 2 3  2001 shanghai	 A	 3 4  2001 shanghai	 B	 4 5  2002  beijing	 A	 5 6  2002  beijing	 B	 6 7  2002 shanghai	 A	 7 8  2002 shanghai	 B	 8 9  2003  beijing	 A	 9 10 2003  beijing	 B	10 11 2003 shanghai	 A	11 12 2003 shanghai	 B	12 > tapply(df$sale, df[,c('year','loc')], sum)    loc year	beijing shanghai   2001		 3		  7   2002		11		 15   2003		19		 23 > tapply(df$sale, df[,c('year','type')], sum)    type year	 A  B   2001  4  6   2002 12 14   2003 20 22

      Reference

      Andrew Lim  

      https://screamyao.wordpress.com/2011/05/03/various-apply-functions-in-r-explained/  

      https://nsaunders.wordpress.com/2010/08/20/a-brief-introduction-to-apply-in-r/  

      http://www.ats.ucla.edu/stat/r/library/advanced_function_r.htm#apply


      来源:http://www.cnblogs.com/aquastone/p/r-apply.html 


      更多精彩内容,请点击阅读原文。

      数据人网(http://shujuren.org),数据人学习、交流和分享的家园,专注于从数据中学习,努力发觉数据之洞见,积极利用数据之价值。为“让人懂数据、用数据”之使命坚持做点事情。大家可以来投稿,做分享和传播,可以给反馈。您有什么想法,请反馈给我们,谢谢。数据人网,我们共建和共享。

      数据人网构建了数据人圈子,诚邀热爱数据和利用数据朋友入群。加小编微信:luqin360,注明入圈子。

             数据人网官方公众号:数据科学自媒体,分享数据科学干货。

            

             【R知识】R语言apply函数族笔记



      测试结尾

      请关注“恒诺新知”微信公众号,感谢“R语言“,”数据那些事儿“,”老俊俊的生信笔记“,”冷🈚️思“,“珞珈R”,“生信星球”的支持!

      • 分享:
      作者头像
      weinfoadmin

      上一篇文章

      【R扩展包】caret包运用
      2016年3月10日

      下一篇文章

      【R】提升R代码运算效率的11个实用方法
      2016年3月11日

      你可能也喜欢

      3-1665801675
      R语言学习:重读《R数据科学(中文版)》书籍
      28 9月, 2022
      6-1652833487
      经典铁死亡,再出新思路
      16 5月, 2022
      1-1651501980
      R语言学习:阅读《R For Everyone 》(第二版)
      1 5月, 2022

      搜索

      分类

      • R语言
      • TCGA数据挖掘
      • 单细胞RNA-seq测序
      • 在线会议直播预告与回放
      • 数据分析那些事儿分类
      • 未分类
      • 生信星球
      • 老俊俊的生信笔记

      投稿培训

      免费

      alphafold2培训

      免费

      群晖配置培训

      免费

      最新博文

      Nature | 单细胞技术揭示衰老细胞与肌肉再生
      301月2023
      lncRNA和miRNA生信分析系列讲座免费视频课和课件资源包,干货满满
      301月2023
      如何快速批量修改 Git 提交记录中的用户信息
      261月2023
      logo-eduma-the-best-lms-wordpress-theme

      (00) 123 456 789

      weinfoadmin@weinformatics.cn

      恒诺新知

      • 关于我们
      • 博客
      • 联系
      • 成为一名讲师

      链接

      • 课程
      • 事件
      • 展示
      • 问答

      支持

      • 文档
      • 论坛
      • 语言包
      • 发行状态

      推荐

      • iHub汉语代码托管
      • iLAB耗材管理
      • WooCommerce
      • 丁香园论坛

      weinformatics 即 恒诺新知。ICP备案号:粤ICP备19129767号

      • 关于我们
      • 博客
      • 联系
      • 成为一名讲师

      要成为一名讲师吗?

      加入数以千计的演讲者获得100%课时费!

      现在开始

      用你的站点账户登录

      忘记密码?

      还不是会员? 现在注册

      注册新帐户

      已经拥有注册账户? 现在登录

      close
      会员购买 你还没有登录,请先登录
      • ¥99 VIP-1个月
      • ¥199 VIP-半年
      • ¥299 VIP-1年
      在线支付 激活码

      立即支付
      支付宝
      微信支付
      请使用 支付宝 或 微信 扫码支付
      登录
      注册|忘记密码?