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

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

  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 的结构

  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语句如下

  1. select count(score) from students group by subject

用R自带的函数 tapply 也可以实现上面的要求:

  1. > tapply(student$score, students$subject, sum)
  2. su1 su2
  3. 245 253

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

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

  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 < R < 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 < R < 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 < R < D
  28. > tapply(ages, affils, mean)
  29. U  R  D
  30. 21 31 41

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

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

请看下面的例子:

实验数据如下:

  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 的不同性别的总收入

  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, 下面看如下两个例子就清楚明了了

  1. > split(staff$income, list(staff$over25, staff$gender))
  2. $`0.F`
  3. [1] 32450 45650
  4. $`1.F`
  5. [1] 123000
  6. $`0.M`
  7. numeric(0)
  8. $`1.M`
  9. [1] 55000 88000 76500
  10. > split(staff$income, list(staff$gender, staff$over25))
  11. $F.0
  12. [1] 32450 45650
  13. $M.0
  14. numeric(0)
  15. $F.1
  16. [1] 123000
  17. $M.1
  18. [1] 55000 88000 76500

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

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

  1. > split(1:length(staff$gender), staff$gender)
  2. $F
  3. [1] 3 5 6
  4. $M
  5. [1] 1 2 4

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

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

  1. filewords <- function(tf) {
  2. txt <- scan(tf, "")
  3. words <- split(1:length(txt), txt)
  4. return(words)
  5. }

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

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

 
0

r 数据分组处理的更多相关文章

  1. R数据科学-2

    R数据科学(R for Data Science) Part 2:数据处理 导入-->整理-->转换 ------------------第7章 使用tibble实现简单数据框------ ...

  2. R数据科学-1

    R数据科学(R for Data Science) Part 1:探索 by: PJX for 查漏补缺 exercise: https://jrnold.github.io/r4ds-exercis ...

  3. .NET LINQ 数据分组

    数据分组      分组指将数据放入组中以便每个组中的元素共享公共特性的操作.   方法 方法名 说明 C# 查询表达式语法 Visual Basic 查询表达式语法 更多信息 GroupBy 对共享 ...

  4. MySQL:基础—数据分组

    MySQL:基础-数据分组 1.为什么要分组: 比如一个表中有多条订单记录,如上图,每条记录对应着一个商品,现在我要查询 每个商品被订购的单数 准备出货?也就是找到每个商品被订购的数量. 如果只找一个 ...

  5. EMVTag系列1《数据分组》

    数据分组的设计在个人化过程中承担着重要的作用.数据分组标识符(DGI)是两字节十六进制数.数据分组标识的第一个字节等于'01'到'1E',表明数据存储的SFI.第二个字节表明SFI记录的记录编号.其他 ...

  6. SQL从入门到基础 - 05 数据分组、Having语句

    一.数据分组 1. 按照年龄进行分组统计各个年龄段的人数: Select FAge,count(*) from T_Employee group by FAge; 2. Group by子句必须放到w ...

  7. 数据分组分析—-groupby

    数据分组分析—-groupby 代码功能: 对于综合表格data,基于title进行分组处理,并统计每一组的size,得到的是一个series序列,此序列可以放入索引中使用,index() impor ...

  8. pandas学习(数据分组与分组运算、离散化处理、数据合并)

    pandas学习(数据分组与分组运算.离散化处理.数据合并) 目录 数据分组与分组运算 离散化处理 数据合并 数据分组与分组运算 GroupBy技术:实现数据的分组,和分组运算,作用类似于数据透视表 ...

  9. MySQL数据分组Group By 和 Having

    现有以下的学生信息表: 若果现在想计算每个班的平均年龄,使用where的操作如下: SELECT Cno AS 班级, AVG(Sage) AS 平均年龄 FROM stu ; 这样的话,有多少个班就 ...

随机推荐

  1. 谈谈CListCtrl如何调整行高

    原文链接: http://blog.csdn.net/sstower/article/details/9094939 调整CListCtrl 行高通常有3种方法: 1.设定字体2.设定图片3.处理Me ...

  2. CView类的使用

    首先我们来写一个样例: 1.建一个win32简单应用程序,不要觉得这样就不能写出MFC程序,由于是不是MFC程序取决于调没调MFC函数. 2. 删除入口函数.仅仅留下#include "st ...

  3. 多主机共享ssh Public/Private Key

    前期服务器比较少,所有代码都放在github的私库中,在自己的github 设置中设置SSH keys就可以拉下相应的库中的代码到本地与服务器了,但是最近服务器多家了几台,每台都生成key加到gith ...

  4. oracle递归层级查询 start with connect by prior

    递归层级查询:start with connect by prior  以部门表作为解析 表结构:dept{id:'主键',name:'部门名称',parent_id:'父亲id'} select * ...

  5. 限制 nuget 更新包的版本号

    今天在搜索其它问题的时候,突然发现一个使用 nuget 的小技巧. 因为浏览器兼容性的问题,很多网站项目引用的 jQuery 组件版本需要保持在 2.0 以下,因为 2.0 以上需要现代浏览器的支持, ...

  6. ssh:Permissions 0644 for ‘/root/.ssh/id_rsa’ are too open

    最近,用ssh连接github时,突然提示“Permissions 0644 for ‘/root/.ssh/id_rsa’ are too open”,并且断开连接. 仔细阅读了一下ssh文档和这句 ...

  7. 把Xilinx的IPCORE解密成源代码的方法

    把Xilinx的IPCORE解密成源代码的方法   1.加密的文件格式以can_v1_5/can_tl_bsp.vhd为例子a)前8个字节XlxV38EB是加密的版本号,没研究过其他加密版本,不知道有 ...

  8. leetcode ---双指针+滑动窗体

    一:Minimum Size Subarray Sum(最小长度子数组的和O(N)) 题目: Given an array of n positive integers and a positive ...

  9. Java并发编程之并发代码设计

    引子 之前的文章我们探讨了引发线程安全的原因主要是由于多线程的对共享内存的操作导致的可见性或有序性被破坏,从而导致内存一致性的错误.那么如何设计并发代码解决这个问题呐?我们一般使用这几种方式: 线程封 ...

  10. 解决MAC下ctags -R无效的问题

    MAC下自带了ctags,与我们常用的是不同的. 我们需要去重新下载一个ctags并重新安装 1.去http://ctags.sourceforge.net/下载Ctags的最新版本源代码 2.tar ...