R语言笔记7:认识循环函数、lapply和sapply |
您所在的位置:网站首页 › r语言中数据集中的变量求和是什么 › R语言笔记7:认识循环函数、lapply和sapply |
R语言基础系列: 你知道R中的赋值符号箭头( x x $a [,1] [,2] [1,] 1 3 [2,] 2 4 $b [,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6 我现在想提取每个矩阵的第一列,结果发现没这个函数。 那么就来创造一个函数提取矩阵的第一列: > lapply(x, function(elt) { elt[,1] }) $a [1] 1 2 $b [1] 1 2 3在我临时创造的函数里面,命名了一个参数叫elt,用于提取第一行,其实你想叫他什么都可以因为出了lapply()之后他就毫无意义了。 所以使用lapply()的时候就知道了,有函数就用,没有就现写 sapply()sapply()是lapply()的变种。它的任务是将lapply()的结果尽量的简化。 lapply()总是返回一个列表。就算是所有元素长度都一样,没必要是一个列表的时候,他也给你返回列表。 sapply()就会更加灵活一些,可以直接返回一个包含所有元素的向量,将它简化。 对比: 先看一下“一根筋”的lapply() > x lapply(x, mean) $a [1] 2.5 $b [1] 0.1983592 $c [1] 0.8517163 $d [1] 5.145514再来看一下sapply(): > x sapply(x, mean) a b c d 2.50000000 -0.02155822 1.22162680 4.96242076如果数据不适合简化的话,sapply()还是会返回一个列表的。 applyapply函数是另一个循环函数,它可以把一个函数应用在一个数组的各个维度上,应用对象是矩阵的行和列。(矩阵是最常见的数组类型,是二维数组) 在命令行中apply比for循环相对更好用一些,因为输入较少。 apply函数长这样: > str(apply) function (X, MARGIN, FUN, ...)第一个参数x是一个数组,是一个有维度的向量; 第二个参数MARGIN是一个整数向量,指示哪一行或列需要保留; 第三个重要参数是你要应用到每个行、列的函数命令,这个函数可以是已经存在的函数,也可以是匿名函数。 第四个参数...是其他你想传递的参数 举例 首先创建一个20行10列的矩阵,矩阵内是已生成的正态随机变量: > x apply(x, 2, mean) [1] 0.65874106 -0.32984283 0.02339061 0.07329736 -0.03052147 [6] -0.07784829 -0.09898670 -0.02616803 -0.62234169 0.21103926同理,如果我想求每一行的数据之和,那么就指定MARGIN为1,只保留所有行(第一维度),消掉所有列。得到长度为20 的向量: > apply(x, 1, sum) [1] 1.2437406 1.2477988 -0.8286921 5.8799087 -7.1345567 [6] -6.0516633 1.1861021 -4.6233625 1.4116391 4.0984832 [11] 0.6733807 -4.2918003 6.3707265 0.5751055 -4.1153285 [16] -2.4731258 -1.5706162 2.1357355 4.5665875 -2.6848776对于计算总和、平均值之类的简单操作而言,有一些经过优化的专用函数可以快速实现这些功能,他们就是~~: rowSums() = apply(x, 1, sum) rowMeans() = apply(x, 1, mean) colSums() = apply(x, 2, sum) colMeans()= apply(x, 2, mean) 所以上面的对矩阵x的各行求和,可以直接用这些函数: > rowSums(x) [1] 1.2437406 1.2477988 -0.8286921 5.8799087 -7.1345567 [6] -6.0516633 1.1861021 -4.6233625 1.4116391 4.0984832 [11] 0.6733807 -4.2918003 6.3707265 0.5751055 -4.1153285 [16] -2.4731258 -1.5706162 2.1357355 4.5665875 -2.6848776apply()函数也可以应用在复杂一点的命令上。 还是以刚才的随机数矩阵为例,我们想计算每一行的25%和75%分位数,使用quantile()函数,...用来传递其他参数,结果如下(每一行都会有对应的两个返回值): > apply(x, 1, quantile, probs = c(0.25, 0.75)) [,1] [,2] [,3] [,4] [,5] 25% -0.4279914 -0.7373156 -0.9529599 0.2055977 -1.212583 75% 0.7124124 0.6271725 0.4206316 1.1519559 -0.164044 [,6] [,7] [,8] [,9] [,10] 25% -1.5083933 -0.4973032 -1.40098143 -0.1734262 0.1533103 75% 0.2944026 0.2808402 -0.03580914 0.7878205 1.1799618 [,11] [,12] [,13] [,14] [,15] 25% -0.7556971 -1.3682307 -0.09161202 -0.0714848 -1.170791 75% 0.6127445 0.5407379 1.60144594 0.3402383 0.186875 [,16] [,17] [,18] [,19] [,20] 25% -0.4673410 -0.5190178 -0.4813278 -0.3519997 -1.083816 75% 0.2163925 0.4672890 0.4078020 1.1469154 -0.117494除了二维矩阵之外,apply也可以用于多维矩阵,即数组 如,我们先创建一个正态随机变量数组,是一个三维矩阵,然后求每个二维矩阵的和, 设置MARGIN为c(1, 2)就可以消除掉第三个维度: > a apply(a, c(1, 2), mean) [,1] [,2] [1,] 0.4376722 0.1558857 [2,] 0.5024186 -0.2940285同理,如果使用rowMeans: > rowMeans(a, dims = 2) [,1] [,2] [1,] 0.4376722 0.1558857 [2,] 0.5024186 -0.2940285 mapply()mapply()是lapply()和sapply()的多变量版本 也就是说 lapply()和sapply()等等都是将参数中的函数应用到某个单一的对象上,而mapply()的思想是把一个函数并行应用到一组不同的对象上 > str(mapply) function (FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE, USE.NAMES = TRUE)mapply()的第一个参数是你要应用的函数, 第二个...用于传递参数 第三个参数是MoreArgs当你需要给函数传递更多参数是才会用到 tapplytapply是一个很有用的函数,它可以将函数应用于某向量的子集。 当我们想计算该向量某部分的概要统计量时,可以使用tapply。 对于该数值向量中的每一组而言,我们都可以计算一个统计量,这时,我们需要另一个变量或者对象,来识别该数值向量中各元素的分组。 > str(tapply) function (X, INDEX, FUN = NULL, ..., default = NA, simplify = TRUE)第一个参数是数值或者其他类型的向量 第二个参数INDEX是另一个向量,长度和第一个向量相同,用来表明第一个向量中的各个元素分别属于哪一组。 第三个参数FUN是你想应用的函数。 举例 x是一个数组向量,其中包括10个正态随机数、10个均匀随机数、10个均值是1的正态随机数;这些数字可以分成三组,用函数gl()创建因子变量,这个因子变量有三个水平,每个水平重复10次: > x f x [1] -1.22192295 1.23396169 -0.74551533 0.10967076 -1.89038874 [6] 1.51580225 0.44769556 0.64438076 0.33981352 1.14463578 [11] 0.19257671 0.66332397 0.98498225 0.64714562 0.63170090 [16] 0.20529137 0.05715295 0.85430414 0.19152730 0.72570007 [21] -0.68530428 1.19698816 0.79573025 1.93891480 1.50044997 [26] 2.72678274 0.44608262 0.96684451 1.59033947 0.19885301 > f [1] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 Levels: 1 2 3应用tapply()函数,求每组数据的平均值 > tapply(x, f, mean, simplify = FALSE) $`1` [1] 0.1578133 $`2` [1] 0.5153705 $`3` [1] 1.067568如果设置为不简化,那么结果将返回一个列表。 返回观测值的范围,range()得到每组中的最大值和最小值: > tapply(x, f, range) $`1` [1] -1.890389 1.515802 $`2` [1] 0.05715295 0.98498225 $`3` [1] -0.6853043 2.7267827参考资料: 视频课程 R Programming by Johns Hopkins University:https://www.coursera.org/learn/r-programming/home/welcome 讲义 Programming for Data Science :https://bookdown.org/rdpeng/rprogdatascience/R 欢迎大家跟我一起上车~~~~请关注 10000+:肠道细菌 人体上的生命 宝宝与猫狗 梅毒狂想曲 提DNA发Nature 实验分析谁对结果影响大 Cell微生物专刊 系列教程:微生物组入门 Biostar 微生物组 宏基因组 专业技能:生信宝典 学术图表 高分文章 不可或缺的人 一文读懂:宏基因组 寄生虫益处 进化树 必备技能:提问 搜索 Endnote 文献阅读 热心肠 SemanticScholar Geenmedical 扩增子分析:图表解读 分析流程 统计绘图 16S功能预测 PICRUSt FAPROTAX Bugbase Tax4Fun 在线工具:16S预测培养基 生信绘图 科研经验:云笔记 云协作 公众号 编程模板 Shell R Perl 生物科普 生命大跃进 细胞暗战 人体奥秘 写在后面为鼓励读者交流、快速解决科研困难,我们建立了“宏基因组”专业讨论群,目前己有国内外150+ PI,1500+ 一线科研人员加入。参与讨论,获得专业解答,欢迎分享此文至朋友圈,并扫码加主编好友带你入群,务必备注“姓名-单位-研究方向-职称/年级”。技术问题寻求帮助,首先阅读《如何优雅的提问》学习解决问题思路,仍末解决群内讨论,问题不私聊,帮助同行。 学习16S扩增子、宏基因组科研思路和分析实战,关注“宏基因组” 点击阅读原文,跳转最新文章目录阅读 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |