R语言中的循环函数(Grouping Function)

简介:

R语言中有几个常用的函数,可以按组对数据进行处理,apply, lapply, sapply, tapply, mapply,等。这几个函数功能有些类似,下面介绍下这几个函数的用法。

Apply

这是对一个Matrix或者Array进行某个维度的运算。其格式是:

Apply(数据,维度Index,运算函数,函数的参数)

对于Matrix来说,其维度值为2,第二个参数维度Index中,1表示按行运算,2表示按列运算。下面举一个例子:

m<-matrix(1:6,2,3)

构建一个简单的2行3列的矩阵,内容为:

     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
如果我们要计算每一行的sum值,那么我们可以写为:
apply(m,1,sum)
[1]  9 12
如果要计算每一列的mean值,那么改为:
apply(m,2,mean)
[1] 1.5 3.5 5.5
假如某个值为NA,那么要忽略NA值,进行每一行的SUM怎么办呢?
m[2,2]<-NA
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2   NA    6
apply(m,1,sum)
[1]  9 NA
本身sum函数有一个参数na.rm,我们可以将这个参数带人到apply函数中,作为第4个参数:
apply(m,1,sum,na.rm=TRUE)
[1] 9 8
需要注意的是如果是Data Frame,那么系统会将其转为Matrix,如果所有Column不是数字类型或者类型不一致,导致转换失败,那么apply是运算不出任何一列的结果的。

Lapply

前面说到apply是对于matrix和array的,针对list,我们可以使用lapply函数。该函数接收list,返回的结果也是一个list。其调用如下:
Apply(数据,运算函数,函数的参数)
对于Data Frame来说,如果不同的列有不同的数据类型,不能转换成Matrix,但是却可以转换成List,然后使用lapply函数。
我们建立一个学生名字,年龄和成绩的Data Frame,然后统计平均年龄和平均成绩,由于name列不是数值类型,所以无法算平均值,所以我们可以对非数值的数据只取count数量。这里就需要用到自定义函数。
函数可以是匿名函数,也可以是之前定义好的函数,由于这里逻辑简单,我们可以用匿名函数解决。

s<-data.frame(name=c("Devin","Edward","Lulu"),age=c(30,33,29),score=c(95,99,90))

    name age score
1  Devin  30    95
2 Edward  33    99
3   Lulu  29    90


lapply(s,function(x){if(is.numeric(x)){mean(x)}else{length(x)}})

$name
[1] 3

$age
[1] 30.66667

$score
[1] 94.66667
我们可以看到返回了一个List的结果,里面包含3个项,每个项是函数执行的结果。lapply返回的结果和传入的List的结构相同,传入多少个Item,返回的也是多少个Item。

Sapply

Sapply函数和Lapply函数很类似,也是对List进行处理,只是在返回结果上,Sapply会根据结果的数据类型和结构,重新构建一个合理的数据类型返回。调用格式如下:
Apply(数据,运算函数,函数的参数,simplify = TRUE, USE.NAMES = TRUE)
对于其中的simplify参数,就是指明是否对返回的结果集重新组织,如果为FALSE,那么就相当于lapply了。USE.NAMES是对字符串数据处理时,是否使用字符串作为命名的。
还是上面的例子,只是把lapply换成sapply:
sapply(s,function(x){if(is.numeric(x)){mean(x)}else{length(x)}})
    name      age    score 
 3.00000 30.66667 94.66667 
我们可以看到结果集变成了一个数字向量,而不是List了。

Mapply

这是对多个数据(multivariate)进行sapply处理,只是调用是参数位置有所变化,先把函数放前面:
mapply(运算函数,函数的参数,第一个传入参数,第二个数据…,SIMPLIFY = TRUE,USE.NAMES = TRUE)
比如我们自定义一个函数m3,接受3个数值参数,然后将3个数字相乘返回结果:
m3<-function(a,b,c){a*b*c}
然后我们构建3个向量,他们具有相同的长度:

a<-1:5
b<-2:6
c<-5:1

现在我们要求a,b,c中的对应各位数进行m3函数的运算,也就是把a,b,c的第一个数做运算,然后把a,b,c的第二个数做运算,然后第三个数~~~这时候就用mapply很方便:

mapply(m3,a,b,c)
[1] 10 24 36 40 30

OK,就这么简单,实现了对应的各位元素的运算。

Tapply

前面介绍的几个apply函数都是对整体数据进行处理,而tapply是对向量中的数据进行分组处理。先看看tapply函数的调用格式:
tapply(向量数据,分组标识,运算函数,函数的参数,simplify = TRUE)
我们以一个学生数据的Data Frame为例来讲解tapply函数,先构建一个新的学生数据,包含name,age,score,class,gender:

s<-data.frame(name=c("Devin","Edward","Lulu","Jeneen"),age=c(30,33,29,32),score=c(95,99,90,88),class=c(1,2,1,2),gender=c("M","M","F","F"))

    name age score class gender
1  Devin  30    95     1      M
2 Edward  33    99     2      M
3   Lulu  29    90     1      F
4 Jeneen  32    88     2      F

如果我们要计算每个班的平均成绩,那么使用tapply的方法是:

tapply(s$score,s$class,mean)
   1    2 
92.5 93.5 
如果改为按gender算平均成绩,那么就是:
tapply(s$score,s$gender,mean)
 F  M 
89 97 
如果同时按class和gender来看呢?这里就需要把两个向量构建成list作为第二个参数传入:
tapply(s$score,list(s$class,s$gender),mean)
   F  M
1 90 95

2 88 99


本文转自深蓝居博客园博客,原文链接:http://www.cnblogs.com/studyzy/p/4355082.html,如需转载请自行联系原作者

相关文章
|
6月前
|
人工智能 Python
083_类_对象_成员方法_method_函数_function_isinstance
本内容主要讲解Python中的数据类型与面向对象基础。回顾了变量类型(如字符串`str`和整型`int`)及其相互转换,探讨了加法在不同类型中的表现。通过超市商品分类比喻,引出“类型”概念,并深入解析类(class)与对象(object)的关系,例如具体橘子是橘子类的实例。还介绍了`isinstance`函数判断类型、`type`与`help`探索类型属性,以及`str`和`int`的不同方法。最终总结类是抽象类型,对象是其实例,不同类型的对象有独特运算和方法,为后续学习埋下伏笔。
114 7
083_类_对象_成员方法_method_函数_function_isinstance
|
6月前
|
Python
[oeasy]python086方法_method_函数_function_区别
本文详细解析了Python中方法(method)与函数(function)的区别。通过回顾列表操作如`append`,以及随机模块的使用,介绍了方法作为类的成员需要通过实例调用的特点。对比内建函数如`print`和`input`,它们无需对象即可直接调用。总结指出方法需基于对象调用且包含`self`参数,而函数独立存在无需`self`。最后提供了学习资源链接,方便进一步探索。
123 17
|
6月前
|
人工智能 Python
[oeasy]python083_类_对象_成员方法_method_函数_function_isinstance
本文介绍了Python中类、对象、成员方法及函数的概念。通过超市商品分类的例子,形象地解释了“类型”的概念,如整型(int)和字符串(str)是两种不同的数据类型。整型对象支持数字求和,字符串对象支持拼接。使用`isinstance`函数可以判断对象是否属于特定类型,例如判断变量是否为整型。此外,还探讨了面向对象编程(OOP)与面向过程编程的区别,并简要介绍了`type`和`help`函数的用法。最后总结指出,不同类型的对象有不同的运算和方法,如字符串有`find`和`index`方法,而整型没有。更多内容可参考文末提供的蓝桥、GitHub和Gitee链接。
128 11
|
12月前
|
数据挖掘 C语言 C++
R语言是一种强大的统计分析工具,提供了丰富的函数和包用于时间序列分析。
【10月更文挑战第21天】时间序列分析是一种重要的数据分析方法,广泛应用于经济学、金融学、气象学、生态学等领域。R语言是一种强大的统计分析工具,提供了丰富的函数和包用于时间序列分析。本文将介绍使用R语言进行时间序列分析的基本概念、方法和实例,帮助读者掌握R语言在时间序列分析中的应用。
246 3
|
12月前
|
JavaScript
箭头函数与普通函数(function)的区别
箭头函数是ES6引入的新特性,与传统函数相比,它有更简洁的语法,且没有自己的this、arguments、super或new.target绑定,而是继承自外层作用域。箭头函数不适用于构造函数,不能使用new关键字调用。
|
11月前
|
中间件 Docker Python
【Azure Function】FTP上传了Python Function文件后,无法在门户页面加载函数的问题
通过FTP上传Python Function至Azure云后,出现函数列表无法加载的问题。经排查,发现是由于`requirements.txt`中的依赖包未被正确安装。解决方法为:在本地安装依赖包到`.python_packages/lib/site-packages`目录,再将该目录内容上传至云上的`wwwroot`目录,并重启应用。最终成功加载函数列表。
119 0
|
数据可视化 开发者 索引
详解Wireshark LUA插件函数:function p_myproto.dissector(buffer, pinfo, tree)
在 Wireshark 中,LUA 插件通过 `function p_myproto.dissector(buffer, pinfo, tree)` 扩展协议解析能力,解析自定义应用层协议。参数 `buffer` 是 `PacketBuffer` 类型,表示原始数据包内容;`pinfo` 是 `ProtoInfo` 类型,包含数据包元信息(如 IP 地址、协议类型等);`tree` 是
500 1
|
12月前
|
JavaScript
箭头函数与普通函数(function)的区别
箭头函数是ES6引入的新语法,相比传统函数表达式更简洁,且没有自己的this、arguments、super或new.target绑定,而是继承自外层作用域。这使得箭头函数在处理回调和闭包时更加灵活方便。
|
12月前
|
C++ 容器
函数对象包装器function和bind机制
函数对象包装器function和bind机制
87 0

热门文章

最新文章