重要函数的使用

重要函数:
处理循环:R不仅有for/while语句,还有更强大的实现循环的“”一句话”函数:
例如:lapply,sapply,apply,mapply,tapply
排序: sort, order
总结数据信息:

1. lapply: 循环处理列表的每一个元素的函数

lapply(列表,函数/函数名,其他参数), 如果输入的不是列表会强制转换成列表,且总是返回一个列表。

>str(lapply)   #将对象以简洁的方式展现出来,可以用这个函数查看某些函数的使用方式等
function (X, FUN, ...)
>x=list(a=1:10,b=c(11,21,31,41,51))
>lapply(x,mean) #对列表x中的每一个元素执行函数mean功能,并返回一个列表
$a
[1] 5.5

$b
[1] 31

#runif函数,从一个均匀分布的整体里抽取若干个数,没有设定min和max,则默认从0到1间抽取。
>x=1:4
>lapply(x,runif)#对向量x中的每一个元素执行函数runif函数功能 ,此处x输入lapply时就强制转换成了列表  
[[1]]
[1] 0.5071569

[[2]]  #x的第2个元素为2,表示使用runif函数从0到1中抽取2个元素
[1] 0.7498979 0.4167026

[[3]]
[1] 0.3318948 0.7376890 0.8953933

[[4]]
[1] 0.3661408 0.8690727 0.7495184 0.6303936

 ##runif函数加min和max参数,表示抽取范围为min到max之间。
>x=1:4
>lapply(x,runif,min=0,max=100) 
[[1]]
[1] 33.60319

[[2]]
[1] 10.39440 15.01912

[[3]]
[1] 40.760076 80.177156  8.579981

[[4]]
[1] 36.112842  5.754629 52.333730 20.258521

lapply函数总是和匿名函数一起使用

>x=list(a=matrix(1:6,2,3),b=matrix(4:7,2,2))
>lapply(x,function(m) m[1,]) #匿名函数m设置的功能是取出矩阵的第一行;将这个函数使用到列表x的每一个矩阵中
$a
[1] 1 3 5

$b
[1] 4 6

拓展:sapply函数

sapply函数和apply函数非常像,不同的是它可以将apply的结果进行化简(如果能化简的前提下)

>x=list(a=1:10,b=c(11,21,31,41,51))
> lapply(x,mean)
$a
[1] 5.5

$b
[1] 31
> class(lapply(x,mean))
[1] "list"

#sapply在lapply的基础上进行了简化,将lapply的返回值列表简化成一个向量。
> sapply(x,mean)
   a    b 
 5.5 31.0 

> class(sapply(x,mean))
[1] "numeric"

总结:

lapply:可以循环处理列表中的每一个元素,lapply(列表,函数/函数名,其他参数),总是返回一个列表。
sapply:简化结果:
结果列表元素长度均为1,返回向量;
结果列表元素长度相同且大于1,返回矩阵。
结构列表元素长度不相同,则无法返回向量或矩阵,则无法简化,此时返回结果与lapply返回结果一样。

2. apply函数

apply的作用是沿着矩阵或数组的某一个维度处理数据。
apply(数组,维度,函数/函数名)

##apply用于矩阵上时,表示沿着矩阵的行或列应用某个函数
>x=matrix(1:16,4,4)
>apply(x,2,mean)   #2表示沿着第二维度(即按列),mean表示求平均
[1]  2.5  6.5 10.5 14.5
>apply(x,2,sum)   #sum表示求和
[1] 10 26 42 58

###求和求平均的函数还可以用以下函数
>rowSums(x)     #按行求和
>rowMeans(x)    #按行求平均
>colSums(x)
>colMeans(x)

###apply函数更复杂的用法
>x=matrix(rnorm(100),10,10) #随机从正态分布(默认mean=0,sd=1)里抽取100个数,排成10行10列的矩阵
>apply(x,1,quantile, probs=c(0.25,0.75)) #quantile函数功能是取百分位点,probs参数限定取百分位点0.25和0.75对应的数据
          [,1]      [,2]       [,3]       [,4]       [,5]       [,6]      [,7]       [,8]       [,9]
25% -0.8698191 0.1834426 -0.7151516 -0.7226345 -0.4760617 -0.3621392 0.3263838 -0.9957614 -0.8140163
75%  0.1321196 0.9225007  0.3939212  0.3600644  0.8427925  0.6938235 1.0108419  0.5014759  0.4611247
         [,10]
25% -0.7366401
75%  0.7528281

##apply在数组上的应用
>x=array(rnorm(2*3*4),c(2,3,4))
>apply(x,c(1,2),mean)
          [,1]        [,2]      [,3]
[1,] 0.6826388 -0.05148654 0.6598627
[2,] 0.9493935  1.07309431 0.1900946

3. mapply函数的使用

mapply是lapply的多元版本,mapply(函数/函数名,数据,函数相关参数)

##例1:
> list(rep(1,4),rep(2,3),rep(3,2),rep(4,1))
[[1]]
[1] 1 1 1 1

[[2]]
[1] 2 2 2

[[3]]
[1] 3 3

[[4]]
[1] 4
>mapply(rep,1:4,4:1) #等价于上面使用4次rep
[[1]]
[1] 1 1 1 1

[[2]]
[1] 2 2 2

[[3]]
[1] 3 3

[[4]]
[1] 4

将mapply与自定义的函数结合使用

使用function(参数1){函数(参数2)}设置自己想要的函数,参数1和2保持一致。

>s=function(n,mean,std){rnorm(n,mean,std)} #定义一个取正态分布的函数s
>s(4,0,1) #从均值为0标准差为1的正态分布里抽取4个数据
[1]  0.02827703  0.78118912 -2.21107882 -1.32102919
>list(s(1,5,2),s(2,4,2),s(3,3,2),s(4,2,2),s(5,1,2))#生成一个列表
[[1]]
[1] 3.540876

[[2]]
[1] 7.051226 1.943815

[[3]]
[1]  1.6773376  0.5642655 -0.9923016

[[4]]
[1] 4.479538 2.996352 2.874110 2.378267

[[5]]
[1]  1.2305284  2.4137494 -0.9950734 -1.7734084  1.1782496

#以上生成列表的方法可以用mapply函数快速生成
>mapply(s,1:5,5:1,2) #1:5对应s()函数中的第1个参数4,5:1对应s()函数中的第2个参数0,2对应s()函数中的第3个参数1.
[[1]]
[1] 3.540876

[[2]]
[1] 7.051226 1.943815

[[3]]
[1]  1.6773376  0.5642655 -0.9923016

[[4]]
[1] 4.479538 2.996352 2.874110 2.378267

[[5]]
[1]  1.2305284  2.4137494 -0.9950734 -1.7734084  1.1782496


4. tapply函数的使用

tapply函数对向量的子集进行操作,tapply(向量,因子/因子列表,函数名)

>x=c(rnorm(5),runif(5),rnorm(5,1)) #创建包含15个元素的向量,分别来自正态分布,均匀分布和均值为1的正态分布
>f=gl(3,5) #使用gl()函数创建一个因子,这个因子包含3个水平,每个水平下5个元素
[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
Levels: 1 2 3
>tapply(x,f,mean) #使用tapply()函数,对向量x,按照f因子进行分组,对每一组求均值。
         1          2          3 
-0.4139614  0.6019100  0.3027485

#tapply函数有一个默认参数simplify=TRUE,这个参数的功能是对返回值进行简化,如:将返回的列表简化成矩阵形式。
>tapply(x,f,mean,simplify=FALSE) #使simplify参数为FALSE,返回值是一个列表。
$`1`
[1] -0.4139614

$`2`
[1] 0.60191

$`3`
[1] 0.3027485

5.split函数的使用

split函数的作用是根据因子或因子列表将向量或其他对象分组,通常与lapply一起使用。
split(向量/列表/数据框,因子/因子列表)

###例1:还是使用上面的例子
>x=c(rnorm(5),runif(5),rnorm(5,1)) 
>f=gl(3,5)
>split(x,f)
$`1`
[1]  2.4163880  0.3688412 -0.8332317 -1.2660243 -0.1656017

$`2`
[1] 0.4877443 0.1797565 0.7013813 0.2955032 0.1029182

$`3`
[1] -0.09358635  2.94570706  0.71325020  1.05274496  0.71446343

>lapply(split(x,f),mean) #lapply函数对分组后的列表按照每个元素取均值
$`1`
[1] 0.1040743

$`2`
[1] 0.3534607

$`3`
[1] 1.066516

###例2:使用R内置的数据集
>head(airquality)
  Ozone Solar.R Wind Temp Month Day
1    41     190  7.4   67     5   1
2    36     118  8.0   72     5   2
3    12     149 12.6   74     5   3
4    18     313 11.5   62     5   4
5    NA      NA 14.3   56     5   5
6    28      NA 14.9   66     5   6
>s=split(airquality,airquality$Month)  #按照月份对这个数据框进行分组
>table(airquality$Month)  #含有5个月,每个月下有不同的记录数
 5  6  7  8  9 
31 30 31 31 30
>lapply(s,function(x)colMeans(x[,c("Ozone","Wind","Temp")]))
$`5`
   Ozone     Wind     Temp 
      NA 11.62258 65.54839 

$`6`
   Ozone     Wind     Temp 
      NA 10.26667 79.10000 

$`7`
    Ozone      Wind      Temp 
       NA  8.941935 83.903226 

$`8`
    Ozone      Wind      Temp 
       NA  8.793548 83.967742 

$`9`
Ozone  Wind  Temp 
   NA 10.18 76.90 
#使用sapply()函数进行简化
> sapply(s,function(x)colMeans(x[,c("Ozone","Wind","Temp")]))
             5        6         7         8     9
Ozone       NA       NA        NA        NA    NA
Wind  11.62258 10.26667  8.941935  8.793548 10.18
Temp  65.54839 79.10000 83.903226 83.967742 76.90

#在colMeans这个函数中加入参数na.rm=TRUE去除缺失值所在行。
>sapply(s,function(x)colMeans(x[,c("Ozone","Wind","Temp")],na.rm=TRUE)) 
             5        6         7         8        9
Ozone 23.61538 29.44444 59.115385 59.961538 31.44828
Wind  11.62258 10.26667  8.941935  8.793548 10.18000
Temp  65.54839 79.10000 83.903226 83.967742 76.90000

6. 排序

sort函数对向量进行排序,返回排好序的内容;
order函数返回排好序的内容的下标,并且可以按照多个排序标准进行排序

>x=data.frame(v1=1:5,v2=c(10,7,9,6,8),v3=11:15,v4=c(1,1,2,2,1))
>x
  v1 v2 v3 v4
1  1 10 11  1
2  2  7 12  1
3  3  9 13  2
4  4  6 14  2
5  5  8 15  1
>sort(x$v2) #sort返回排好序的内容,默认升序
[1]  6  7  8  9 10
>sort(x$v2,decreasing=TRUE) 
[1] 10  9  8  7  6
> order(x$v2) #sort返回排好序的下标,默认升序
[1] 4 2 5 3 1
> x[order(x$v2),] #因为order返回排好序的下标,所以可以利用这个对数据框进行排序
  v1 v2 v3 v4
4  4  6 14  2
2  2  7 12  1
5  5  8 15  1
3  3  9 13  2
1  1 10 11  1

###按照多个排序标准对数据框排序
>x[order(x$v4,x$v2),] #先按照v4升序,在v4变量一致的前提下再按照v2升序
  v1 v2 v3 v4
2  2  7 12  1
5  5  8 15  1
1  1 10 11  1
4  4  6 14  2
3  3  9 13  2
>x[order(x$v4,x$v2,decreasing=TRUE),] #按照降序排序

7. 总结数据信息(summarize the data)

> head(airquality,10) #head指定查看前6行,可以给定数字指定查看前几行。
> tail(airquality) #查看最后6行
> summary(airquality) #对数据的总体分布有一个清楚的总结
     Ozone           Solar.R           Wind             Temp      
 Min.   :  1.00   Min.   :  7.0   Min.   : 1.700   Min.   :56.00  
 1st Qu.: 18.00   1st Qu.:115.8   1st Qu.: 7.400   1st Qu.:72.00  
 Median : 31.50   Median :205.0   Median : 9.700   Median :79.00  
 Mean   : 42.13   Mean   :185.9   Mean   : 9.958   Mean   :77.88  
 3rd Qu.: 63.25   3rd Qu.:258.8   3rd Qu.:11.500   3rd Qu.:85.00  
 Max.   :168.00   Max.   :334.0   Max.   :20.700   Max.   :97.00  
 NA's   :37       NA's   :7                                       
     Month            Day      
 Min.   :5.000   Min.   : 1.0  
 1st Qu.:6.000   1st Qu.: 8.0  
 Median :7.000   Median :16.0  
 Mean   :6.993   Mean   :15.8  
 3rd Qu.:8.000   3rd Qu.:23.0  
 Max.   :9.000   Max.   :31.0 

> str(airquality) #以一种简洁的方式对数据进行总结
'data.frame':   153 obs. of  6 variables:
 $ Ozone  : int  41 36 12 18 NA 28 23 19 8 NA ...
 $ Solar.R: int  190 118 149 313 NA NA 299 99 19 194 ...
 $ Wind   : num  7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
 $ Temp   : int  67 72 74 62 56 66 65 59 61 69 ...
 $ Month  : int  5 5 5 5 5 5 5 5 5 5 ...
 $ Day    : int  1 2 3 4 5 6 7 8 9 10 ...
> table(airquality$Month) #table函数对某列变量进行总结

 5  6  7  8  9 
31 30 31 31 30
>table(airquality$Ozone) #table函数默认忽略NA值
 1   4   6   7   8   9  10  11  12  13  14  16  18  19  20  21  22  23  24 
  1   1   1   3   1   3   1   3   2   4   4   4   4   1   4   4   1   6   2 
 27  28  29  30  31  32  34  35  36  37  39  40  41  44  45  46  47  48  49 
  1   3   1   2   1   3   1   2   2   2   2   1   1   3   2   1   1   1   1 
 50  52  59  61  63  64  65  66  71  73  76  77  78  79  80  82  84  85  89 
  1   1   2   1   1   2   1   1   1   2   1   1   2   1   1   1   1   2   1 
 91  96  97 108 110 115 118 122 135 168 
  1   1   2   1   1   1   1   1   1   1 
>table(airquality$Ozone,useNA="ifany") #给参数保留NA值
 1    4    6    7    8    9   10   11   12   13   14   16   18   19   20 
   1    1    1    3    1    3    1    3    2    4    4    4    4    1    4 
  21   22   23   24   27   28   29   30   31   32   34   35   36   37   39 
   4    1    6    2    1    3    1    2    1    3    1    2    2    2    2 
  40   41   44   45   46   47   48   49   50   52   59   61   63   64   65 
   1    1    3    2    1    1    1    1    1    1    2    1    1    2    1 
  66   71   73   76   77   78   79   80   82   84   85   89   91   96   97 
   1    1    2    1    1    2    1    1    1    1    2    1    1    1    2 
 108  110  115  118  122  135  168 <NA> 
   1    1    1    1    1    1    1   37

> table(airquality$Month,airquality$Day)#table也可以同时看两列数据信息,形成一个行位月份,列为天数的矩阵
   
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
  5 1 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
  6 1 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
  7 1 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
  8 1 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
  9 1 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
   
    28 29 30 31
  5  1  1  1  1
  6  1  1  1  0
  7  1  1  1  1
  8  1  1  1  1
  9  1  1  1  0
>any(is.na(airquality$Ozone)) #统计一下数据airquality的Ozone列是否有缺失值
[1] TRUE
>sum(is.na(airquality$Ozone)) #统计一下缺失值的数量
[1] 37
>all(airquality$Month<12) #判断数据的月份是不是都小于12
[1] TRUE

##Titanic数据
> class(Titanic)
[1] "table"
>titanic=as.data.frame(Titanic)
>head(titanic)
  Class    Sex   Age Survived Freq
1   1st   Male Child       No    0
2   2nd   Male Child       No    0
3   3rd   Male Child       No   35
4  Crew   Male Child       No    0
5   1st Female Child       No    0
6   2nd Female Child       No    0
>dim(titanic)
[1] 32  5
> summary(titanic)
  Class       Sex        Age     Survived      Freq       
 1st :8   Male  :16   Child:16   No :16   Min.   :  0.00  
 2nd :8   Female:16   Adult:16   Yes:16   1st Qu.:  0.75  
 3rd :8                                   Median : 13.50  
 Crew:8                                   Mean   : 68.78  
                                          3rd Qu.: 77.00  
                                          Max.   :670.00 

交叉表

交叉表用于查看两个变量的交叉信息

>x=xtabs(Freq ~ Class+Age, data=titanic) #查看class和age的交叉频率
> x
      Age
Class  Child Adult
  1st      6   319
  2nd     24   261
  3rd     79   627
  Crew     0   885
> class(x)
[1] "xtabs" "table"
>ftable(x) #内容与xtabs()一样,但是排版更加扁平了
> ftable(x)
      Age Child Adult
Class                
1st           6   319
2nd          24   261
3rd          79   627
Crew          0   885

查看数据大小

>object.size(airquality)
5632 bytes
>print(object.size(airquality),units="kb")
5.5 Kb
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容