• 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
     
  • 相关阅读:
    sort()
    type()
    reverse()
    pop()
    remove()
    max()
    len()
    Ext.Js核心函数( 三)
    聚簇索引和非聚簇索引区别
    Ext.js入门(二)
  • 原文地址:https://www.cnblogs.com/studyzy/p/4355082.html
Copyright © 2020-2023  润新知