基本数据管理
4.1 准备
创建数据框
mydata<-data.frame(manager=numeric(0),data=character(0),country=character(0),gender=character(0),age=numeric(0),q1=numeric(0),q2=numeric(0),q3=numeric(0),q4=numeric(0),q5=numeric(0))
mydata<-edit(mydata)
打开,只需运行mydata<-edit(mydata)
第二种方法
manager<-c(1,2,3,4,5)
date<-c("10/24/08","10/28/08","10/1/08","10/12/08","5/1/09")
country<-c("US","US","UK","UK","UK")
gender<-c("M","F","F","M","F")
age<-c(32,45,25,39,99)
q1 <- c(5,3,3,3,2)
q2 <- c(4,5,5,3,2)
q3 <- c(5,2,5,4,1)
q4 <- c(5,5,5,NA,2)
q5 <- c(5,5,2,NA,1)
leadership<-data.frame(manager,date,country,gender,age,q1,q2,q3,q4,q5,stringsAsFactors = FALSE)
这个表格的q1~q5是上上司对经理人的打分。
拿到这个表格,我们做数据管理,可能需要作如下处理:五个评分(q1~q5)的综合处理,对不完整数据的处理(无效数据如99,缺失数据如NA)。只取出对这项分析有用的数据(数据提取),数据重命名,数据变换(数据的另一种展示方式)等。本章将介绍这些数据管理方式。
4.2 创建新变量
对原有变量的运算。这里通过例子展示
mydata<-data.frame(x1 = c(2, 2, 6, 4),
x2 = c(3, 4, 2, 8))
有三种方式:
1.直接运算
mydata$sumx <- mydata$x1 + mydata$x2
mydata$meanx <- (mydata$x1 + mydata$x2)/2
2. 与上一种差别是:用attach()和detach()这一对函数,让R知道变量在mydata里面,因此,每个变量前不用再添加数据框。
需要注意的是,原来没有的变量(sumx和meanx)还是要加数据框,否则生成的sumx和meanx不会在数据框。我的理解是,attach()函数使用在前,只是告诉R此时数据框的变量有什么,但是没有告诉R新生成的变量是放在哪里的,如果不加“数据框$变量”,新生成的变量仍旧是游离的。
attach(mydata)
mydata$sumx <- x1 + x2
mydata$meanx <- (x1 + x2)/2
detach(mydata)
它简化了按需创建新变量并保存到数据框的过程。
mydata <- transform(mydata,
sumx = x1 + x2,
meanx = (x1 + x2)/2)
4.3 变量的重新编码
同过原有变量创新值(在机器学习里,应该就相当于特征变换)
变量名[条件]<-expression 仅在条件为真时,值为TRUE
重新编码这里介绍两种方式
一、
leadership$agecat[leadership$age > 75] <- "Elder"
leadership$agecat[leadership$age >= 55 &
leadership$age <= 75] <- "Middle Aged"
leadership$agecat[leadership$age < 55] <- "Young"
二、
leadership <- within(leadership,{
agecat <- NA
agecat[age > 75] <- "Elder"
agecat[age >= 55 & age <= 75] <- "Middle Aged"
agecat[age < 55] <- "Young" })
4.4 变量的重命名
三种方式
一、交互式
fix(leadership)
二、函数names()
> names(leadership)
[1] "manager" "date" "gender" "age" "q1" "q2" "q3"
[8] "q4" "q5" "agecat"
> names(leadership)[2] <- "testDate"
> leadership
manager testDate gender age q1 q2 q3 q4 q5 agecat
1 1 10/24/08 M 32 5 4 5 5 5 Young
2 2 10/28/08 F 45 3 5 2 5 5 Young
3 3 10/1/08 F 25 3 5 5 5 2 Young
4 4 10/12/08 M 39 3 3 4 NA NA Young
5 5 5/1/09 F 99 2 2 1 2 1 Elder
三、plyr包中的rename()函数
library(plyr)
leadership <- rename(leadership,
c(manager="managerID", date="testDate"))
4.5 缺失值
主要从几个方面分析缺失值:缺失值是什么,该如何标记它,如何设置它。遇到缺失值时,怎么排除。
- 缺失值:NA(not available,不可用)
- is.nan( )检测缺失值,返回相当大小的对象,元素是逻辑值
- 设置缺失值
leadership$age[leadership$age==99]<-NA
所有等于age中未99的都设置为缺失值标记NA。- 排除缺失值函数的帮助文档:很多函数有na.rm=TRUE选项,使用可在计算前移除缺失值并用剩余值计算。
x <- c(1, 2, NA, 3)
y <- sum(x, na.rm=TRUE)
> y
[1] 6
- 不同函数可能有不同处理缺失值的方式,使用前可哟弄帮助文档查询。行删除:na.omit()移除所有含缺失的观测,以上体为例:
> na.omit(leadership)
manager date gender age q1 q2 q3 q4 q5
1 1 10/24/08 M 32 5 4 5 5 5
2 2 10/28/08 F 45 3 5 2 5 5
3 3 10/1/08 F 25 3 5 5 5 2
- 第4和第5行都有NA,因此,结果只剩下1、2、3行的观测。
行删除不适用于缺失值非常多的数据中。
4.6日期指
以字符串性质输入到R中,再转化成署执行时存储。as.Date()用于这种转化
日期的默认输入格式为yyyy-mm-dd。
as.Date("日期",“输入格式”),通过指定格式读取字符型变量,并将其作为一个日期变量替换到数据框中,之后就可以对这项日期进行分析和绘图。
> mydates <- as.Date(c("2007-06-22", "2004-02-13"))
> mydates
[1] "2007-06-22" "2004-02-13"
> strDates <- c("01/05/1965", "08/16/1975")
> dates <- as.Date(strDates, "%m/%d/%Y")
> dates
[1] "1965-01-05" "1975-08-16"
>
> strDates
[1] "01/05/1965" "08/16/1975"
两个常用的函数:
Sys.Date( )返回当天的日期
date( )返回当前的日期和时间。
> Sys.Date()
[1] "2017-12-27"
> date()
[1] "Wed Dec 27 12:55:18 2017"
可通过format(x,format="输出格式“)为输出指定日期值和提取日期中的某些部分。
> today <- Sys.Date()
> format(today, format="%B %d %Y")
[1] "十二月 27 2017"
> format(today, format="%A")
[1] "星期三"
日期计算:
> # Calculations with with dates
> startdate <- as.Date("2004-02-13")
> enddate <- as.Date("2009-06-22")
> enddate - startdate
Time difference of 1956 days
difftime()计算时间间隔
> # Date functions and formatted printing
> today <- Sys.Date()
> dob <- as.Date("1956-10-12")
> difftime(today, dob, units="weeks")
Time difference of 3193.714 weeks
> dob
[1] "1956-10-12"
> today
[1] "2017-12-27"
4.6.1 日期转化为字符型变量
strDates<-as.character(dates)
4.6.2 关于日期的一些函数和包
可查看help(as.Date)、help(strftime)。lubridate包、timeDate包
4.7 类型转换
向数值型向量添加一个字符串,则此向量所有元素转换为字符型
判断 | 转换 |
is.numeric() | as.numeric() |
is.character() | as.character() |
is.vector() | as.vector() |
is.matrex() | as.matrix() |
is.data.frame() | as.data.frame() |
is.factor() | as.factor() |
is.logical() | as.logical() |
4.8 数排序
order()可对数据框排序,默认升序。在排序变量加减号,变成降序。
newdata<-leadership[order(leadership$age),]
leadership数据框中的数据按年龄升序排序
attach(leadership)
newdata<-leadership[order(gender,age)]
detach(leadership)
先按女性到男性排,同性别中,按年龄升序排
attach(leadership)
newdata<-leadership[order(gender,age)]
detach(leadership)
先按女性到男性排,同性别中,按年龄降序排
4.9 数据集的合并
内联结(inner join)
- merge()函数
total<- merge(dataframeA, dataframeB,by="ID")
数据集dataframeA, dataframeB通过ID进行合并
total<- merge(dataframeA, dataframeB,by=c("ID","Country"))
数据集dataframeA, dataframeB按照ID和Country进行合并
横向合并(不需要指定一个公共索引)
- total<-cblind(A,B)
横向合并A和B(对象具有相同的行数)
纵向合并(向数据框添加行)
- total<-rblind(dataframeA,dataframeB)
注意:A和B要有相同的对象,也就是列数要相同,但顺序不一定要相同。
4.10 数据集取子集(感觉类似机器学习中的特征选择)
4.10.1选入(保留)变量
通过下标选择和通过引号中的变量名选择
newdata <- leadership[, c(6:10)]
# 选择leadership的第6列到底9列
结果为
> newdate
q2 q3 q4 q5
1 4 5 5 5
2 5 2 5 5
3 5 5 5 2
4 3 4 NA NA
5 2 1 2 1
> myvars<-paste("q",1:5,sep="")
> myvars
[1] "q1" "q2" "q3" "q4" "q5"
#得到一组向量,再放入数据框的方括号中作为引用
> newdate<-leadership[myvars]
> newdate
q1 q2 q3 q4 q5
1 5 4 5 5 5
2 3 5 2 5 5
3 3 5 5 5 2
4 3 3 4 NA NA
5 2 2 1 2 1
4.10.2 剔除(丢弃)变量
names(leadership)
myvars<-names(leadership)%in%c("q3","q4")
newdata<-leadership[!myvars]
> names(leadership)
[1] "manager" "date" "gender" "age" "q1" "q2" "q3"
[8] "q4" "q5"
> names(leadership)%in%c("q3","q4")
[1] FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE
> !myvars
[1] TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE TRUE
> newdata
manager date gender age q1 q2 q5
1 1 10/24/08 M 32 5 4 5
2 2 10/28/08 F 45 3 5 5
3 3 10/1/08 F 25 3 5 2
4 4 10/12/08 M 39 3 3 NA
5 5 5/1/09 F 99 2 2 1
names(leadership)生成一个包含所有变量名的字符型向量
names(leadership)%in%c("q3","q4") :每个与q3和q4匹配的元素值为TRUE,反之为FALSE
可以看到q3和q4最后被剔除了。- 加“-”
> newdata<-leadership[c(-8,-9)]
> newdata
manager date gender age q1 q2 q3
1 1 10/24/08 M 32 5 4 5
2 2 10/28/08 F 45 3 5 2
3 3 10/1/08 F 25 3 5 5
4 4 10/12/08 M 39 3 3 4
5 5 5/1/09 F 99 2 2 1
- 可以看到第8列和第9列被删除了。
- 设为未定义(NULL,注意NULL与NA不同)
leadership$q3<-leadership$q4<- NULL
4.10.3 选入观测
newdata <- leadership[1:3,]
newdata <- leadership[leadership$gender=="M" &
leadership$age > 30,]
attach(leadership)
newdata <- leadership[gender=='M' & age > 30,]
detach(leadership)
# Selecting observations based on dates
leadership$date<-as.Date(leadership$date,"%m/%d/%y") #将mm/dd//yy作为读入字符值的格
3式,转换为日期期
startdate <- as.Date("2009-01-01") #as.Data的默认格式就是yyyy-mm-dd,所以不同再提供输入格#式的参数
enddate <- as.Date("2009-10-31")
newdata <- leadership[which(leadership$date >= startdate &
leadership$date <= enddate),]
原表格 输出表格
4.10.4 subset()
newdata <- subset(leadership, age >= 35 | age < 24, select=c(q1, q2, q3, q4))
选择q1、q2、q3、q4列,并且保留的观测是满足年龄在小于24,但大于35之间的。
newdata <- subset(leadership, gender=="M" & age > 25, select=gender:q4)
4.10.5 随机抽样
sample(从中抽样的数据行数向量,抽样个数,是否放回FALSE为无放回)
mysample<-leadership[sample(1:nrow(leadership),3,replace=FALSE)]
中间过程
> 1:nrow(leadership)[1] 1 2 3 4 5
结果
> mysample date q1 age1 10/24/08 5 322 10/28/08 3 45
3 10/1/08 3 25
4 10/12/08 3 39
5 5/1/09 2 99
随机抽了3列