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

时间:2024-05-23 08:25:59

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

一、排序

1、单变量序列排序

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

  给一个例子:

  1. > a <- c(3, 1, 5)
  2. > rank(a)
  3. [1] 2 1 3
  4. > sort(a)
  5. [1] 1 3 5
  6. > order(a)
  7. [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)数据集为例:

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

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

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

  升序:

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

  降序:

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


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

  1. library(dplyr)
  2. ## Sepal.Width升序
  3. arrange(iris, Sepal.Width)
  4. ## Sepal.Width降序
  5. arrange(iris, desc(Sepal.Width))
  6. ## Sepal.Width升序,当Sepal.Width相同时按Petal.Length降序
  7. arrange(iris, Sepal.Width,-Petal.Length)
R语言:排序、筛选以及分类汇总操作

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

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

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

 

二、筛选

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

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

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

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

  1. >iris[which(iris$Sepal.Width > 4), ]
  2. Sepal.Length Sepal.Width Petal.LengthPetal.Width Species
  3. 16 5.7 4.4 1.5 0.4 setosa
  4. 33 5.2 4.1 1.5 0.1 setosa
  5. 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内的判别式作为索引因也可以达到相同的筛选目的:

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

 

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

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

 

三、分类汇总

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

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

  1. >a <- split(iris$Sepal.Width, iris$Species)
  2. >sapply(a, mean)
  3. setosa versicolor virginica
  4. 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组合自动舍弃

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