zoukankan      html  css  js  c++  java
  • r 数据分组处理

    一、R语言实现数据的分组求和

    实验数据集 姓名,年龄,班级 ,成绩, 科目

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. student <- data.frame (  
    2.   name = c("s1", "s2", "s3", "s2", "s1", "s3"),  
    3.   age = c(12, 13, 10, 13, 12, 10),  
    4.   classid = c("c1", "c2", "c3", "c2", "c1", "c3"),  
    5.   score = c(78, 68, 99, 81, 82, 90),  
    6.   subject = c("su1", "su1", "su1", "su2", "su2", "su2")  
    7. )  

    下面看看 students 的结构
    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. > str(students)  
    2. 'data.frame':   6 obs. of  5 variables:  
    3.  $ name   : Factor w/ 3 levels "s1","s2","s3": 1 2 3 2 1 3  
    4.  $ age    : num  12 13 10 13 12 10  
    5.  $ classid: Factor w/ 3 levels "c1","c2","c3": 1 2 3 2 1 3  
    6.  $ score  : num  78 68 99 81 82 90  
    7.  $ subject: Factor w/ 2 levels "su1","su2": 1 1 1 2 2 2  

    可以看到,在调用 data.frame 函数之后,默认将字符形变量转换成了因子变量,并且重新对它们进行编码

    下面我们求每个班级平均成绩:用SQL语句如下

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. select count(score) from students group by subject  

    用R自带的函数 tapply 也可以实现上面的要求:
    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. > tapply(student$score, students$subject, sum)  
    2. su1 su2   
    3. 245 253   

    从tapply的执行结果我们可以看出,tapply 是根据第二个变量因子变量(注意必须是因子变量)对第一个变量来分组,然后对所有分成的小组调用最后的函数

    再来看一个例子,加深对因子的理解:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. > affils <- c("R", "D", "D", "R", "U", "D")  
    2. > affils <- as.factor(x = affils)  
    3. > affils  
    4. [1] R D D R U D  
    5. Levels: D R U  
    6. > affils <- factor(affils, ordered = TRUE)  
    7. > affils  
    8. [1] R D D R U D  
    9. Levels: D U  
    10. > affils <- factor(affils, levels = c("U", "R", "D"),  ordered = TRUE)  
    11. > tapply(ages, affils, mean)  
    12.  U  R  D   
    13. 21 31 41   
    14. > ages <- c(25, 26, 55, 37, 21, 42)  
    15. > affils <- c("R", "D", "D", "R", "U", "D")  
    16. > affils <- as.factor(x = affils)  
    17. > affils  
    18. [1] R D D R U D  
    19. Levels: D R U  
    20. > affils <- factor(affils, ordered = TRUE)  
    21. > affils  
    22. [1] R D D R U D  
    23. Levels: D U  
    24. > affils <- factor(affils, levels = c("U", "R", "D"),  ordered = TRUE)  
    25. > affils  
    26. [1] R D D R U D  
    27. Levels: U D  
    28. > tapply(ages, affils, mean)  
    29.  U  R  D   
    30. 21 31 41   

    从例子中可以发现,因子的水平,以及水平的高低我们都是可以按照自己的想法去控制的

    好了,有了上面的基础知识,下面进一步加大难度,如果分组变量有几个呢?

    请看下面的例子:

    实验数据如下:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. > staff <- data.frame(list(gender = c("M", "M", "F", "M", "F", "F"),  
    2. +                      age = c(47, 59, 21, 32, 33, 24),  
    3. +                      income = c(55000, 88000, 32450, 76500, 123000, 45650)  
    4. +                      )  
    5. +                 )  
    6. > staff  
    7.   gender age income  
    8. 1      M  47  55000  
    9. 2      M  59  88000  
    10. 3      F  21  32450  
    11. 4      M  32  76500  
    12. 5      F  33 123000  
    13. 6      F  24  45650  
    14. > str(staff)  
    15. 'data.frame':   6 obs. of  3 variables:  
    16.  $ gender: Factor w/ 2 levels "F","M": 2 2 1 2 1 1  
    17.  $ age   : num  47 59 21 32 33 24  
    18.  $ income: num  55000 88000 32450 76500 123000 ...  

    下面分析:年龄大于 25 的不同性别的总收入,以及年龄小于 25 的不同性别的总收入
    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. > staff$over25 <- ifelse(staff$age > 25, 1, 0)  
    2. > staff  
    3.   gender age income over25  
    4. 1      M  47  55000      1  
    5. 2      M  59  88000      1  
    6. 3      F  21  32450      0  
    7. 4      M  32  76500      1  
    8. 5      F  33 123000      1  
    9. 6      F  24  45650      0  
    10. > tapply(staff$income, list(staff$gender, staff$over25), sum)  
    11.       0      1  
    12. F 78100 123000  
    13. M    NA 219500  

    从结果中可以清楚的看到,年龄小于 25 的女员工总收入为 78100, 其他的同理可以分析出来

    二、如果你只是想分组呢?那么你就要要用到 spit 函数,注意字符串的分割是用 strsplit, 下面看如下两个例子就清楚明了了

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. > split(staff$income, list(staff$over25, staff$gender))  
    2. $`0.F`  
    3. [1] 32450 45650  
    4.   
    5. $`1.F`  
    6. [1] 123000  
    7.   
    8. $`0.M`  
    9. numeric(0)  
    10.   
    11. $`1.M`  
    12. [1] 55000 88000 76500  
    13.   
    14. > split(staff$income, list(staff$gender, staff$over25))  
    15. $F.0  
    16. [1] 32450 45650  
    17.   
    18. $M.0  
    19. numeric(0)  
    20.   
    21. $F.1  
    22. [1] 123000  
    23.   
    24. $M.1  
    25. [1] 55000 88000 76500  

    从上面的例子我们可以非常清楚的明白 split 函数的工作原理

    下面看一个有意思的例子,利用 split 迅速定位上面男性的下标,一种非常自然的想法是排序,然后如果数据总是变化无常怎么定位我们想要的那一类数据的下标呢?

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. > split(1:length(staff$gender), staff$gender)  
    2. $F  
    3. [1] 3 5 6  
    4.   
    5. $M  
    6. [1] 1 2 4  

    如果我们将这个方法与文本挖掘联想到一起,我们可以发现,这个方法可以非常容易的解决英文文本词汇索引的问题:

    如果给你一个文本文件,假设单词都是按照空格分割,现在要统计哪些单词出现在文本中,以及出现的位置和次数,我们可以用下面的方法非常容易的解决

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. filewords <- function(tf) {  
    2.   txt <- scan(tf, "")  
    3.   words <- split(1:length(txt), txt)  
    4.   return(words)  
    5. }  

    另外我们应该关注 by() 函数的使用

    最后一句话:在R中如果可以不使用循环则力求不使用

     
    0
  • 相关阅读:
    innodb的存储结构
    使用zabbix邮件发送报表
    如何使用yum下载rpm包
    redis cluster节点管理测试
    redis迁移工具-redis-migrate-tool使用测试
    redis客户端连接异常
    redis sentinel基本命令与参数
    [转]redis-cli的一些有趣也很有用的功能
    [转]为什么使用 Redis及其产品定位
    Redis多机常用架构-cluster
  • 原文地址:https://www.cnblogs.com/awishfullyway/p/6601466.html
Copyright © 2011-2022 走看看