《R语言实战》之 基本数据管理(第四章)

基本数据管理

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)

 3. 这个在书中的前面章节比较少见,直接用函数把运算打包起来,较上一种方法,完全不需要再引用数据框,它简化了按需创建新变量并保存到数据框的过程

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 缺失值

 主要从几个方面分析缺失值:缺失值是什么,该如何标记它,如何设置它。遇到缺失值时,怎么排除。

  1. 缺失值:NA(not available,不可用)
  2. is.nan( )检测缺失值,返回相当大小的对象,元素是逻辑值
  3. 设置缺失值
    leadership$age[leadership$age==99]<-NA
    


    所有等于age中未99的都设置为缺失值标记NA。

  4. 排除缺失值
    函数的帮助文档:很多函数有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 age
1 10/24/08  5  32
2 10/28/08  3  45
3  10/1/08  3  25
4 10/12/08  3  39
5   5/1/09  2  99

 随机抽了3列

posted @ 2017-12-28 23:55  CassieLin  阅读(761)  评论(0编辑  收藏  举报