r 数据分组处理
一、R语言实现数据的分组求和
实验数据集 姓名,年龄,班级 ,成绩, 科目
- student <- data.frame (
- name = c("s1", "s2", "s3", "s2", "s1", "s3"),
- age = c(12, 13, 10, 13, 12, 10),
- classid = c("c1", "c2", "c3", "c2", "c1", "c3"),
- score = c(78, 68, 99, 81, 82, 90),
- subject = c("su1", "su1", "su1", "su2", "su2", "su2")
- )
下面看看 students 的结构
- > str(students)
- 'data.frame': 6 obs. of 5 variables:
- $ name : Factor w/ 3 levels "s1","s2","s3": 1 2 3 2 1 3
- $ age : num 12 13 10 13 12 10
- $ classid: Factor w/ 3 levels "c1","c2","c3": 1 2 3 2 1 3
- $ score : num 78 68 99 81 82 90
- $ subject: Factor w/ 2 levels "su1","su2": 1 1 1 2 2 2
可以看到,在调用 data.frame 函数之后,默认将字符形变量转换成了因子变量,并且重新对它们进行编码
下面我们求每个班级平均成绩:用SQL语句如下
- select count(score) from students group by subject
用R自带的函数 tapply 也可以实现上面的要求:
- > tapply(student$score, students$subject, sum)
- su1 su2
- 245 253
从tapply的执行结果我们可以看出,tapply 是根据第二个变量因子变量(注意必须是因子变量)对第一个变量来分组,然后对所有分成的小组调用最后的函数
再来看一个例子,加深对因子的理解:
- > affils <- c("R", "D", "D", "R", "U", "D")
- > affils <- as.factor(x = affils)
- > affils
- [1] R D D R U D
- Levels: D R U
- > affils <- factor(affils, ordered = TRUE)
- > affils
- [1] R D D R U D
- Levels: D < R < U
- > affils <- factor(affils, levels = c("U", "R", "D"), ordered = TRUE)
- > tapply(ages, affils, mean)
- U R D
- 21 31 41
- > ages <- c(25, 26, 55, 37, 21, 42)
- > affils <- c("R", "D", "D", "R", "U", "D")
- > affils <- as.factor(x = affils)
- > affils
- [1] R D D R U D
- Levels: D R U
- > affils <- factor(affils, ordered = TRUE)
- > affils
- [1] R D D R U D
- Levels: D < R < U
- > affils <- factor(affils, levels = c("U", "R", "D"), ordered = TRUE)
- > affils
- [1] R D D R U D
- Levels: U < R < D
- > tapply(ages, affils, mean)
- U R D
- 21 31 41
从例子中可以发现,因子的水平,以及水平的高低我们都是可以按照自己的想法去控制的
好了,有了上面的基础知识,下面进一步加大难度,如果分组变量有几个呢?
请看下面的例子:
实验数据如下:
- > staff <- data.frame(list(gender = c("M", "M", "F", "M", "F", "F"),
- + age = c(47, 59, 21, 32, 33, 24),
- + income = c(55000, 88000, 32450, 76500, 123000, 45650)
- + )
- + )
- > staff
- gender age income
- 1 M 47 55000
- 2 M 59 88000
- 3 F 21 32450
- 4 M 32 76500
- 5 F 33 123000
- 6 F 24 45650
- > str(staff)
- 'data.frame': 6 obs. of 3 variables:
- $ gender: Factor w/ 2 levels "F","M": 2 2 1 2 1 1
- $ age : num 47 59 21 32 33 24
- $ income: num 55000 88000 32450 76500 123000 ...
下面分析:年龄大于 25 的不同性别的总收入,以及年龄小于 25 的不同性别的总收入
- > staff$over25 <- ifelse(staff$age > 25, 1, 0)
- > staff
- gender age income over25
- 1 M 47 55000 1
- 2 M 59 88000 1
- 3 F 21 32450 0
- 4 M 32 76500 1
- 5 F 33 123000 1
- 6 F 24 45650 0
- > tapply(staff$income, list(staff$gender, staff$over25), sum)
- 0 1
- F 78100 123000
- M NA 219500
从结果中可以清楚的看到,年龄小于 25 的女员工总收入为 78100, 其他的同理可以分析出来
二、如果你只是想分组呢?那么你就要要用到 spit 函数,注意字符串的分割是用 strsplit, 下面看如下两个例子就清楚明了了
- > split(staff$income, list(staff$over25, staff$gender))
- $`0.F`
- [1] 32450 45650
- $`1.F`
- [1] 123000
- $`0.M`
- numeric(0)
- $`1.M`
- [1] 55000 88000 76500
- > split(staff$income, list(staff$gender, staff$over25))
- $F.0
- [1] 32450 45650
- $M.0
- numeric(0)
- $F.1
- [1] 123000
- $M.1
- [1] 55000 88000 76500
从上面的例子我们可以非常清楚的明白 split 函数的工作原理
下面看一个有意思的例子,利用 split 迅速定位上面男性的下标,一种非常自然的想法是排序,然后如果数据总是变化无常怎么定位我们想要的那一类数据的下标呢?
- > split(1:length(staff$gender), staff$gender)
- $F
- [1] 3 5 6
- $M
- [1] 1 2 4
如果我们将这个方法与文本挖掘联想到一起,我们可以发现,这个方法可以非常容易的解决英文文本词汇索引的问题:
如果给你一个文本文件,假设单词都是按照空格分割,现在要统计哪些单词出现在文本中,以及出现的位置和次数,我们可以用下面的方法非常容易的解决
- filewords <- function(tf) {
- txt <- scan(tf, "")
- words <- split(1:length(txt), txt)
- return(words)
- }
另外我们应该关注 by() 函数的使用
最后一句话:在R中如果可以不使用循环则力求不使用
- 顶
- 0
r 数据分组处理的更多相关文章
- R数据科学-2
R数据科学(R for Data Science) Part 2:数据处理 导入-->整理-->转换 ------------------第7章 使用tibble实现简单数据框------ ...
- R数据科学-1
R数据科学(R for Data Science) Part 1:探索 by: PJX for 查漏补缺 exercise: https://jrnold.github.io/r4ds-exercis ...
- .NET LINQ 数据分组
数据分组 分组指将数据放入组中以便每个组中的元素共享公共特性的操作. 方法 方法名 说明 C# 查询表达式语法 Visual Basic 查询表达式语法 更多信息 GroupBy 对共享 ...
- MySQL:基础—数据分组
MySQL:基础-数据分组 1.为什么要分组: 比如一个表中有多条订单记录,如上图,每条记录对应着一个商品,现在我要查询 每个商品被订购的单数 准备出货?也就是找到每个商品被订购的数量. 如果只找一个 ...
- EMVTag系列1《数据分组》
数据分组的设计在个人化过程中承担着重要的作用.数据分组标识符(DGI)是两字节十六进制数.数据分组标识的第一个字节等于'01'到'1E',表明数据存储的SFI.第二个字节表明SFI记录的记录编号.其他 ...
- SQL从入门到基础 - 05 数据分组、Having语句
一.数据分组 1. 按照年龄进行分组统计各个年龄段的人数: Select FAge,count(*) from T_Employee group by FAge; 2. Group by子句必须放到w ...
- 数据分组分析—-groupby
数据分组分析—-groupby 代码功能: 对于综合表格data,基于title进行分组处理,并统计每一组的size,得到的是一个series序列,此序列可以放入索引中使用,index() impor ...
- pandas学习(数据分组与分组运算、离散化处理、数据合并)
pandas学习(数据分组与分组运算.离散化处理.数据合并) 目录 数据分组与分组运算 离散化处理 数据合并 数据分组与分组运算 GroupBy技术:实现数据的分组,和分组运算,作用类似于数据透视表 ...
- MySQL数据分组Group By 和 Having
现有以下的学生信息表: 若果现在想计算每个班的平均年龄,使用where的操作如下: SELECT Cno AS 班级, AVG(Sage) AS 平均年龄 FROM stu ; 这样的话,有多少个班就 ...
随机推荐
- python学习笔记——创建事件对象Event
1 Event对象的基本概述 用 multiprocessing.Event 实现线程间通信,使用multiprocessing.Event可以使一个线程等待其他线程的通知,我们把这个Event传递到 ...
- HDU--Elevator(水题)
Elevator nid=24#time"> Time Limit: 1000ms Memory limit: 32768K 有疑问?点这里^_^ 题目描写叙述 The high ...
- 使用Htmlhelper,创建文本框TextBox
下面通过HtmlHelper帮助类,创建文本框. 首先新建一个实体类,做为下面的例子: using System; using System.Collections.Generic; using Sy ...
- mysql 查询昨天,今天、七天、30天的数据
主要是时间戳转"1993-01-01 00:00:00"的时间格式,然后和当前时间比对CURDATE() 如果字段本身符合正常时间格式,则直接使用即可 今天的数据 SELECT * ...
- mysql-cluster 环境安装&配置
一.mysql-cluster 的介绍: 1.说心里话mysql-cluster这货性能上是不行的,之前一个同事测试了来的结果是8个主机组成的mysql-cluster性能 上搞不过一个单机的mysq ...
- Linux的七个运行级别原理概述
所谓运行级别,简单点来说,运行级别就是操作系统当前正在运行的功能级别.级别是从0到6,具有不同的功能.这些级别定义在/ect/inittab文件中.这个文件是init程序寻找的主要文件,最先运行的服务 ...
- 《Effective Java》读书笔记七(通用程序设计)
No45 将局部变量的作用域最小化 要使局部变量的作用域最小化,最有力的方法就是在第一次使用它的地方声明. 几乎每个局部变量的声明都应该包含一个初始化表达式.如果你还没有足够的信息来对一个变量进行有意 ...
- 【Android】3.1 创建本章示例项目
分类:C#.Android.VS2015.百度地图应用: 创建日期:2016-02-04 注意:本节是在完成了 3.0节介绍的预备知识的基础上继续实现的. 示例1--显示地图并为后续内容做准备 1.运 ...
- cocos2d-x 父节点和子节点执行不同动作
Test6::Test6() { CCSprite* sp1 = CCSprite::create(s_pPathSister1); CCSprite* sp11 = CCSprite::create ...
- python(34):为什么在Python里推荐使用多进程而不是多线程?
最近在看Python的多线程,经常我们会听到老手说:“Python下多线程是鸡肋,推荐使用多进程!”,但是为什么这么说呢? 要知其然,更要知其所以然.所以有了下面的深 ...