R语言:排序、筛选以及分类汇总操作

  在Excel中我们可以很方便的对数据进行排序、筛选、分类汇总等基本操作,R语言中没有这种傻瓜式的一键操作,如何才能完成这种操作?

一、排序

1、单变量序列排序

  单变量序列的排序常用到rank、sort和order函数。

  给一个例子:

> a <- c(3, 1, 5)
> rank(a)
[1] 2 1 3
> sort(a)
[1] 1 3 5
> order(a)
[1] 2 1 3

  

  下面简单解释一下:rank用来计算序列中每个元素的秩,这里的“秩”可以理解为该元素在序列中由小到大排列的次序,上面例子给出的序列[3, 1, 5]中,1最小,5最大,3居中,于是1的秩为1,3的秩为2,5的秩为3,[3, 1, 5]对应的秩的结果就是[2,1, 3];sort函数给出的是排序后的结果,比方说序列[3,1, 5]使用sort按升序规则排序后的结果是[1, 3, 5];而order函数给出的是排序后的序列中各元素在原始序列中的位置,序列[3, 1, 5]按升序规则排序后的结果是[1, 3, 5] ,其中[1, 3, 5]在原始序列中的位置是[2, 1, 3]。

  接下来介绍一下这三个函数的参数:

  rank(x,na.last = TRUE,

        ties.method = c("average","first", "last", "random", "max","min"))

  order(...,na.last = TRUE, decreasing = FALSE,

         method = c("auto","shell", "radix"))

  sort(x,decreasing = FALSE, na.last = NA, ...)

  x或... :要进行排序的序列;

  na.last:表示对缺失值的处理办法,若为TRUE则将缺失值排在最后,若为FALSE则排在最前,若为NA则排序时先将缺失值剔除;

  ties.method:表示对序列有“结”(即序列中存在相同的元素)时的处理方法,可以有"average","first", "last", "random", "max","min"等选择;

  decreasing : 默认为FALSE表示按升序排列,若为TRUE则按降序排列;

  method:表示排序使用的算法,可以有"auto","shell", "radix"等选择。

2、数据表(矩阵)排序

    如何像Excel中那样将数据表按某列升序或降序排列?我们可以使用order函数巧妙的完成这个操作,以R语言自带的鸢尾花(iris)数据集为例:

> head(iris)
 Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2 setosa
2          4.9         3.0          1.4         0.2 setosa
3          4.7         3.2          1.3        0.2  setosa
4          4.6         3.1          1.5         0.2 setosa
5          5.0         3.6          1.4         0.2 setosa
6          5.4         3.9          1.7         0.4 setosa

  可以看到,该数据集有Sepal.Length、Sepal.Width、Petal.Length、Petal.Width和Species五个变量,下面我们按照花萼宽度(Sepal.Width)进行升降序排列:

## 升序
iris[order(iris$Sepal.Width), ]
## 降序
iris[order(iris$Sepal.Width, decreasing= T), ]

  升序:

  降序:


  除此之外,升降序排列还可以使用dplyr包的arrange函数。arrange函数用法简单,使用形式为arrange(数据表名,变量名),如果是降序排列则可以arrange(数据表名,-变量名)或arrange(数据表名,desc(变量名))。特别值得一提的是,arrange函数还有arrange(数据表名,变量名1,变量名2,...)这种形式的用法,表示如果数据在“变量1”的值相同时按照“变量2”排序。

library(dplyr)
## Sepal.Width升序
arrange(iris, Sepal.Width)
## Sepal.Width降序
arrange(iris, desc(Sepal.Width))
## Sepal.Width升序,当Sepal.Width相同时按Petal.Length降序
arrange(iris, Sepal.Width,-Petal.Length)

  通过对比可以看到,使用arrange进行排序后,数据表的行号重新从1开始排列了,而使用order的方式中排序后的数据表的行号仍然使用原始数据表的行号。

 

二、筛选

  许多筛选工作都可以使用which函数完成,例如:

  挑选出iris数据集中Sepal.Width为2的数据:

>iris[which(iris$Sepal.Width == 2), ]
   Sepal.Length Sepal.Width Petal.LengthPetal.Width    Species
61            5           2          3.5           1 versicolor

  挑选出iris数据集中Sepal.Width大于4的数据:

>iris[which(iris$Sepal.Width > 4), ]
   Sepal.Length Sepal.Width Petal.LengthPetal.Width Species
16          5.7         4.4          1.5         0.4 setosa
33          5.2         4.1          1.5         0.1 setosa
34          5.5         4.2          1.4         0.2 setosa

  挑选出iris数据集中Species为setosa的数据:

iris[which(iris$Species== 'setosa'), ]

  如果挑选Species为setosa或virginica的数据呢,当然我们可以用“或”的运算符“|”来构建:

iris[which((iris$Species== 'setosa') | (iris$Species == 'virginica')), ]

  但是我们推荐使用 %in% 操作符,a %in% b 将生成一个与a长度相同的logical序列,依次判断a中的元素是否被包含在b中。因此,上面的筛选问题可以使用 %in% 操作符解决:

iris[which(iris$Species%in% c('setosa', 'virginica')), ]

  当然,不使用which,直接使用which内的判别式作为索引因也可以达到相同的筛选目的:

iris[iris$Sepal.Width== 2, ]
iris[iris$Sepal.Width> 4, ]
iris[iris$Species== 'setosa', ]
iris[(iris$Species== 'setosa') | (iris$Species == 'virginica'), ]
iris[iris$Species%in% c('setosa', 'virginica'), ]

 

  同样,dplyr包也可以进行筛选操作,需使用filter函数。

filter(iris,Sepal.Width == 2)
filter(iris,Sepal.Width > 4)
filter(iris,Species == 'setosa')
filter(iris,Species %in% c('setosa', 'virginica'))

 

三、分类汇总

  假如我们要对iris数据集进行分类汇总,比方说计算不同Species中Sepal.Width的平均值。

  第一种思路是使用split函数和sapply函数,首先将序列Sepal.Width按照Species划分成子集,然后对每个子集求平均:

>a <- split(iris$Sepal.Width, iris$Species)
>sapply(a, mean)
    setosa versicolor  virginica
     3.428     2.770      2.974

  split(x, f,drop = FALSE, ...)

  x      要进行划分的数据

  f      划分的依据,可以是list,表示按list中各变量的Level组合来划分

  drop   默认为FALSE,若为TRUE,当f为list时,各变量的Level组合为空时自动舍弃这一分组


  第二种思路是使用aggregate函数:

  aggregate(x,by, FUN, ..., simplify = TRUE, drop = TRUE)

  x          要分类汇总的数据,可以是各种形式,包括公式形式

  by         分类依据,必须是list形式

  FUN        汇总使用的函数

  simplify  默认为TRUE,表示汇总结果以简化形式表现

  drop      默认为TRUE,表示不存在的Level组合自动舍弃

> aggregate(x = iris$Sepal.Width, by= list(iris$Species), FUN = mean)
    Group.1     x
1    setosa 3.428
2 versicolor 2.770
3 virginica 2.974
> aggregate(x = iris[, 1:2], by =list(iris$Species), FUN = mean)
    Group.1 Sepal.Length Sepal.Width
1    setosa        5.006       3.428
2 versicolor        5.936       2.770
3 virginica        6.588       2.974

  • 123
    点赞
  • 608
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值