第四章:基本数据管理

一 贯穿整章的示例

二 变量的创建、重编码和重命名

三 日期值与缺失值

四 数据类型和类型转换

五 数据集的排序、合并与取子集

 

一 贯穿整章的示例(leadership)

代码4-1 
 1 > manager<-c(1,2,3,4,5)
 2 > date<-c("10/24/08","10/28/08","10/1/08","10/12/08","5/1/09")
 3 > country<-c("us","us","uk","uk","uk")
 4 > gender<-c("m","f","f","m","f")
 5 > age<-c(32,45,25,39,99)
 6 > q1<-c(5,3,3,3,2)
 7 > q2<-c(4,5,5,3,2)
 8 > q3<-c(5,2,5,4,1)
 9 > q4<-c(5,5,5,NA,2)
10 > q5<-c(5,5,2,NA,1)
11 > leadership<-data.frame(manager,date,country,gender,age,
12 +                        q1,q2,q3,q4,q5,stringsAsFactors = FALSE)
13 > leadership
14   manager     date country gender age q1 q2 q3 q4 q5
15 1       1 10/24/08      us      m  32  5  4  5  5  5
16 2       2 10/28/08      us      f  45  3  5  2  5  5
17 3       3  10/1/08      uk      f  25  3  5  5  5  2
18 4       4 10/12/08      uk      m  39  3  3  4 NA NA
19 5       5   5/1/09      uk      f  99  2  2  1  2  1

 二 变量的创建、重编码与重命名

变量的创建

假设有一个数据框mydata,其中有两变量x1和x2,现想创建一个新变量sumx存储这两变量的和,并创建一个新变量meanx存储这两变量的均值,若使用下面代码中的1与2会出错,原因是R不知道x1和x2是来自数据框data,而应用代码3和4

1 >sum<-x1+x2
2 >meanx<-(x1+x2)/2


3 > meanx<-(mydata$x1+mydata$x2) #这样得到的是独立的变量
4 >meanx<-(mydata$x1+mydata$x2)/2

 

创建新变量
代码4-2
方法一:
1 > mydata<-data.frame(x1<-c(2,2,6,4),
2 +                    x2<-c(3,4,2,8))
3 > sumx<-mydata$x1+mydata$x2
4 > meanx<-(mydata$x1+mydata$x2)/2
5 > sumx
6 [1]  5  6  8 12
7 > meanx
8 [1] 2.5 3.0 4.0 6.0
方法二:
1 > attach(mydata)
2 > mydata$sumx<-x1+x2
3 > mydata$meanx<-(x1+x2)/2
4 > mydata$sumx
5 [1]  5  6  8 12
6 > mydata$meanx
7 [1] 2.5 3.0 4.0 6.0
方法三
1 >mydata<-transform(mydata,
2                   sumx<-x1+x2,
3                   meanx<-(x1+x2)/2)

变量重编码

逻辑运算

小于(<)     小于或等于(<=)    大于(>)         大于或等于(>=)      严格等于(==)

不等于(!=)  非x  (!x)            x或y(x|y)      x和y(x&y)             测试x是否为TRUE(isTRUE(x))

语句variable[condition] <- expression将仅在condition的值为TRUE时执行赋值
 1 > leadership$agecat[leadership$age<55]<-"Young"
 2 > leadership$age[leadership$age=="99"] <- NA
 3 > leadership$agecat[leadership$age>75]<-"Elder"
 4 > leadership$agecat[leadership$age>=55 &
 5 +                   leadership$age<=75]<-"Middle Aged"
 6 > leadership$agecat[leadership$age<55]<-"Young"
 7 > leadership
 8   manager     date country gender age q1 q2 q3 q4 q5 agecat
 9 1       1 10/24/08      us      m  32  5  4  5  5  5  Young
10 2       2 10/28/08      us      f  45  3  5  2  5  5  Young
11 3       3  10/1/08      uk      f  25  3  5  5  5  2  Young
12 4       4 10/12/08      uk      m  39  3  3  4 NA NA  Young
13 5       5   5/1/09      uk      f  NA  2  2  1  2  1   <NA>
或
1 > leadership<-within(leadership,{  
 2 +                   agecat<-NA  # 每句后面不能有逗号
 3 +                   agecat[age>75]            <-"Elder"
 4 +                   agecat[age>=55 & age <=75]<-"Middle Aged"
 5 +                   agecat[age<55]            <-"Young"})
 6 > leadership
 7   manager     date country gender age q1 q2 q3 q4 q5 agecat
 8 1       1 10/24/08      us      m  32  5  4  5  5  5  Young
 9 2       2 10/28/08      us      f  45  3  5  2  5  5  Young
10 3       3  10/1/08      uk      f  25  3  5  5  5  2  Young
11 4       4 10/12/08      uk      m  39  3  3  4 NA NA  Young
12 5       5   5/1/09      uk      f  99  2  2  1  2  1  Elder

 函数within和函数with类似,不同的是它允许你修改数据框

 变量重命名

方法一:fix(leadership)

方法二:rename(dataframe,c(oldname=“newname”,oldname=“newname”,....)

方法三:names()

法一: 
 1 > leaderhip
 2   manager     date country gender age q1 q2 q3 q4 q5
 3 1       5 10/24/08      us      m  32  5  4  5  5  5
 4 2       4 10/28/08      us      f  45  3  5  2  5  5
 5 3       3  10/1/08      uk      f  25  3  5  5  5  2
 6 4       2 10/12/08      uk      m  39  3  3  4 NA NA
 7 5       1   5/1/09      uk      f  99  2  2  1  2  1
 8 > fix(leaderhip) # 注意括号是英文括号,不是中文括号
 9 > leaderhip
10   managerID     date country gender age q1 q2 q3 q4 q5
11 1         1 10/24/08      us      m  32  5  4  5  5  5
12 2         2 10/28/08      us      f  45  3  5  2  5  5
13 3         3  10/1/08      uk      f  25  3  5  5  5  2
14 4         4 10/12/08      uk      m  39  3  3  4 NA NA
15 5         5   5/1/09      uk      f  99  2  2  1  2  1
法二: 
 1 > leaderhip<-rename(leaderhip,
 2 +                   c(managerID="manager",date="testDate"))
 3 > leaderhip
 4   manager testDate country gender age q1 q2 q3 q4 q5
 5 1       1 10/24/08      us      m  32  5  4  5  5  5
 6 2       2 10/28/08      us      f  45  3  5  2  5  5
 7 3       3  10/1/08      uk      f  25  3  5  5  5  2
 8 4       4 10/12/08      uk      m  39  3  3  4 NA NA
 9 5       5   5/1/09      uk      f  99  2  2  1  2  1
法三: 
 1 > names(leaderhip)
 2  [1] "manager"  "testDate" "country"  "gender"   "age"      "q1"      
 3  [7] "q2"       "q3"       "q4"       "q5"      
 4 > names(leaderhip)[1]<-"managerID"
 5 > leaderhip
 6   managerID testDate country gender age q1 q2 q3 q4 q5
 7 1         1 10/24/08      us      m  32  5  4  5  5  5
 8 2         2 10/28/08      us      f  45  3  5  2  5  5
 9 3         3  10/1/08      uk      f  25  3  5  5  5  2
10 4         4 10/12/08      uk      m  39  3  3  4 NA NA
11 5         5   5/1/09      uk      f  99  2  2  1  2  1

三 日期值与缺失值

日期值

日期通常以字符串的形式输入到R中,然后转化为数值形式存储的日期变量,函数as.Date()用于执行这种转化,其语法为as.Date(x, "input_format"),其中x字符型数据input_format则是读入日期的适当格式

%d 数字表示的日期(0~31) 例如01~31

%a 缩写的星期名 例如Mon

%A 非缩写的星期名 例如Monday

%m 月份(00~12) 例如00~12

%b 缩写的月份 例如Jan

%B 非缩写的月份 例如January

%y 两位数的年份 例如07

%Y 四位数的年份2007

默认的日期格式为yyyy-mm-dd,语句为:

1 >mydates<-as.Date(c("2015-09-24","2015-09-25"))
2 >mydates 
3 [1] "2015-09-24" "2015-09-25


格式转化
1 >strDates<-c("24/09/2015","25/09/2015")
2 >dates<-as.Date(strDates,"%d/%m/%Y")# 注意 输入的日期转化为对应的日期,其次这里的Y是大写的,
                                            如果这里y小写的话,会出现输出结果时间不对。
                                            注意要加斜杠
3 >dates
4 [1] "2015-09-24" "2015-09-25"

 

例子:
 1 >leadership
 2 > manager     date country gender age q1 q2 q3 q4 q5
 3       1 10/24/08      us      m  32  5  4  5  5  5
 4       2 10/28/08      us      f  45  3  5  2  5  5
 5       3  10/1/08      uk      f  25  3  5  5  5  2
 6       4 10/12/08      uk      m  39  3  3  4 NA NA
 7       5   5/1/09      uk      f  99  2  2  1  2  1
 8 >leadership$date
 9 [1] "10/24/08" "10/28/08" "10/1/08"  "10/12/08" "5/1/09" 
10 >myformat<-"%m/%d/%y"
11 >leadership$date<-as.Date(leadership$date,myformat)# 为什么这个格式不用加斜杠也行,而上面那个要加                                                                                                       斜杠
12 >leadership
13   manager       date country gender age q1 q2 q3 q4 q5
14       1 2008-10-24      us      m  32  5  4  5  5  5
15       2 2008-10-28      us      f  45  3  5  2  5  5
16       3 2008-10-01      uk      f  25  3  5  5  5  2
17       4 2008-10-12      uk      m  39  3  3  4 NA NA
18       5 2009-05-01      uk      f  99  2  2  1  2  1


当前日期
Sys.Date()--返回今天的日期
date()--返回当前日期和时间
1 >Sys.Date()
2 [1] "2015-09-23"
3 >date() #  他人:这种方法返回的是字符串类型 
4 [1] "Wed Sep 23 22:55:26 2015"
5  >today<-Sys.Date()
6 >format(today,format="%B %d %Y") #  格式化当前日期
7 [1] "九月 24 2015"
8 >format(today,format="%A")
9 [1] "星期四"


两日期相减
1  >startdate<-as.Date("2014-09-24")
2  >enddate<-as.Date("2015-09-24")
3  >days<-enddate-startdate
4  >days
5  Time difference of 365 days

 

用difftime()来计算时间间隔,并以星期(weeks),天(days),时(hours),分(minutes),秒(seconds)来表示。
1  > today<-Sys.Date()
2  > wujiadong<-as.Date("1991-10-07")
3  > difftime(today,wujiadong,units = "weeks")
4  Time difference of 1250.429 weeks

此外:利用函数 strDates<-character(date) 可已经两日期变量转成成字符型变量.

       help(as.Date) and help(strftime)查看与日期和时间相关的函数

       相关包:lubridate 

缺失值

1 识别缺失值is.na()
1 > y<-c(1,2,3,NA)
2 > is.na(y)
3 [1] FALSE FALSE FALSE  TRUE
代码4-3
1 > is.na(leaderhip[,6:10])
2      q1    q2    q3    q4    q5
3 1 FALSE FALSE FALSE FALSE FALSE
4 2 FALSE FALSE FALSE FALSE FALSE
5 3 FALSE FALSE FALSE FALSE FALSE
6 4 FALSE FALSE FALSE  TRUE  TRUE
7 5 FALSE FALSE FALSE FALSE FALSE
2 重编码某些值为缺失值
1 > leaderhip$age[leaderhip$age==99]<-NA
2 > leaderhip$age
3 [1] 32 45 25 39 NA
3 在分析中去除缺失值
1 > x<-c(1,2,NA,3)
2 > y<-x[1]+x[2]+x[3]+x[4]
3 > sumx<-y
4 > sumx
5 [1] NA#因有缺失值
6 > x<-c(1,2,NA,3)
7 > y<-sum(x,na.rm=TRUE)#去除x中的缺失值                    # na.rm()删除缺失值
8 > y
9 [1] 6
1 > leaderhip
 2   managerID testDate country gender age q1 q2 q3 q4 q5
 3 1         1 10/24/08      us      m  32  5  4  5  5  5
 4 2         2 10/28/08      us      f  45  3  5  2  5  5
 5 3         3  10/1/08      uk      f  25  3  5  5  5  2
 6 4         4 10/12/08      uk      m  39  3  3  4 NA NA
 7 5         5   5/1/09      uk      f  NA  2  2  1  2  1
 8 > newdata<-na.omit(leaderhip)                          # na.omit()删除带有缺失值的行
 9 > newdata
10   managerID testDate country gender age q1 q2 q3 q4 q5
11 1         1 10/24/08      us      m  32  5  4  5  5  5
12 2         2 10/28/08      us      f  45  3  5  2  5  5
13 3         3  10/1/08      uk      f  25  3  5  5  5  2

四 数据类型与类型转换

ls.numerica() --as.numerica()

is.character()--as.character()

is.vector()--as.vector()

is.matrix()--as.matrix()

is.data.frame()--as.data.frame()

is.factor()--as.factor()

is.logical()--as.logical()

is.datatype()--返回结果是TRUE或FALSE

1  > a<-c(1,2,3)
 2  > a
 3  [1] 1 2 3
 4  > is.numeric(a)
 5  [1] TRUE
 6  > is.vector(a)
 7  [1] TRUE
 8  > a<-as.character(a)
 9  > a
10  [1] "1" "2" "3"
11  > is.numeric(a)
12  [1] FALSE
13  > is.vector(a)
14  [1] TRUE
15  > is.character(a)
16  [1] TRUE

五 数据集的排序、合并与取子集

数据集的排序

1 > newdata<-leadership[order(leadership$age),]
 2   > newdata
 3     manager       date country gender age q1 q2 q3 q4 q5
 4   3       3 2008-10-01      uk      f  25  3  5  5  5  2
 5   1       1 2008-10-24      us      m  32  5  4  5  5  5
 6   4       4 2008-10-12      uk      m  39  3  3  4 NA NA
 7   2       2 2008-10-28      us      f  45  3  5  2  5  5
 8   5       5 2009-05-01      uk      f  99  2  2  1  2  1
 9   attach(leadership)
10  > newdata<-leadership[order(gender,age),]
11  > newdata
12    manager       date country gender age q1 q2 q3 q4 q5
13  3       3 2008-10-01      uk      f  25  3  5  5  5  2
14  2       2 2008-10-28      us      f  45  3  5  2  5  5
15  5       5 2009-05-01      uk      f  99  2  2  1  2  1
16  1       1 2008-10-24      us      m  32  5  4  5  5  5
17  4       4 2008-10-12      uk      m  39  3  3  4 NA NA
18  > newdata<-leadership[order(gender,-age),]
19  > newdata
20    manager       date country gender age q1 q2 q3 q4 q5
21  5       5 2009-05-01      uk      f  99  2  2  1  2  1
22  2       2 2008-10-28      us      f  45  3  5  2  5  5
23  3       3 2008-10-01      uk      f  25  3  5  5  5  2
24  4       4 2008-10-12      uk      m  39  3  3  4 NA NA
25  1       1 2008-10-24      us      m  32  5  4  5  5  5

数据集的合并(向数据框中添加列(变量)和行(观测))

      添加列

要横向合并两个数据框(数据集),请使用merge()函数。在多数情况下,两个数据框是通过一个或多个共有变量进行联结的(即一种内联结,inner join),例如:

total<-merge(dataframeA,dataframeB,by="ID") # 按照ID进行了合并

 or

total<-merge(dataframeA,dataframeB,by=c("ID","Country")) # 按照ID和Country进行了合并

or

total<-cbind(A,B) #  直接横向合并两个矩阵或数据框,并且不需要指定一个公共索引

                            #  每个对象必须拥有相同的行数,且要有相同顺序排序。

       添加行

rbind()--纵向合并两个数据框

total<-rbind(dataframeA,dataframeB) # 两个数据框必须拥有相同的变量,不过它们的顺序不必一定相同。若dataframeA中有dataframeB中没有的变量,则做一下处理:

 删除dataframeA中的多余变量;

 在dataframeB中创建追加的变量并将其值设为NA(缺失)

 

数据集取子集

选入变量
1  >newdata<-leadership[,c(6:10)]
2  > newdata
3    q1 q2 q3 q4 q5
4  1  5  4  5  5  5
5  2  3  5  2  5  5
6  3  3  5  5  5  2
7  4  3  3  4 NA NA
8  5  2  2  1  2  1

 

剔除变量
方法一:
1 > myvars<-names(leadership)%in%c("q3","q4")              解释:(1) names(leadership)生成了一个包含所有变量名的字符型向量
2 > newdata<-leadership[!myvars]                                (2) names(leadership) %in% c("q3", "q4")返回了一个逻辑型向量,names(leadership)
3 > newdata                                                         中每个 匹配q3或q4的元素的值为TRUE,反之为FALSE
4    manager       date country gender age q1 q2 q5             (3) 运算符非(!)将逻辑值反转  
5  1       1 2008-10-24      us      m  32  5  4  5             (4) leadership[c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE,
6  2       2 2008-10-28      us      f  45  3  5  5                 TRUE)]选择了逻辑值为TRUE的列,于是q3和q4被剔除了
7  3       3 2008-10-01      uk      f  25  3  5  2        
8  4       4 2008-10-12      uk      m  39  3  3 NA         
9  5       5 2009-05-01      uk      f  99  2  2  1
方法二:
1  >newdata<-leadership[c(-8,-9)]
2  > newdata
3    manager       date country gender age q1 q2 q5
4  1       1 2008-10-24      us      m  32  5  4  5
5  2       2 2008-10-28      us      f  45  3  5  5
6  3       3 2008-10-01      uk      f  25  3  5  2
7  4       4 2008-10-12      uk      m  39  3  3 NA
8  5       5 2009-05-01      uk      f  99  2  2  1
方法三:
1   leadership$q3<-leadership$q4<-NULL
2  > leadership
3    manager       date country gender age q1 q2 q5
4  1       1 2008-10-24      us      m  32  5  4  5
5  2       2 2008-10-28      us      f  45  3  5  5
6  3       3 2008-10-01      uk      f  25  3  5  2
7  4       4 2008-10-12      uk      m  39  3  3 NA
8  5       5 2009-05-01      uk      f  99  2  2  1

 

subset()函数
1  > newdata<-subset(leadership,age>=35|age<24,
2  +                 select = c(q1,q2,q3,q4))
3  > newdata
4    q1 q2 q3 q4
5  2  3  5  2  5
6  4  3  3  4 NA
7  5  2  2  1  2
1  > newdata<-subset(leadership,gender=="m" & age>25,
2  +                 select = gender:q4)
3  > newdata
4    gender age q1 q2 q3 q4
5  1      m  32  5  4  5  5
6  4      m  39  3  3  4 NA

 

随机抽样
1  > mysample<-leadership[sample(1:nrow(leadership),3,
2  +                      replace=FALSE),]
3  > mysample
4    manager     date country gender age q1 q2 q3 q4 q5
5  4       4 10/12/08      uk      m  39  3  3  4 NA NA
6  5       5   5/1/09      uk      f  99  2  2  1  2  1
7  2       2 10/28/08      us      f  45  3  5  2  5  5

 

使用sql语句操作数据框