R语言实战(基本数据管理)

首先我先创建了一个数据框,后续的操作都依赖于这个数据框

> manager<-c(1,2,3,4,5)
> data<-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,data,country,gender,age,q1,q2,q3,q4,q5,stringsAsFactors = FALSE)
> leadership
  manager     data country gender age q1 q2 q3 q4 q5
1       1 10/24/08      US      M  32  5  4  5  5  5
2       2 10/28/08      US      F  45  3  5  2  5  5
3       3  10/1/08      UK      F  25  3  5  5  5  2
4       4 10/12/08      UK      M  39  3  3  4 NA NA
5       5   5/1/09      UK      F  99  2  2  1  2  1

stringsAsFactors = FALSE,特征向量能否转换为因子,默认TRUE,这里的话就是前四列不作为因子,下面给出了有或者stringsAsFactors = FALSE的区别。

dership<-data.frame(manager,data,country,gender,age,q1,q2,q3,q4,q5)
> str(dership)
'data.frame':	5 obs. of  10 variables:
 $ manager: num  1 2 3 4 5
 $ data   : Factor w/ 5 levels "10/1/08","10/12/08",..: 3 4 1 2 5
 $ country: Factor w/ 2 levels "UK","US": 2 2 1 1 1
 $ gender : Factor w/ 2 levels "F","M": 2 1 1 2 1
 $ age    : num  32 45 25 39 99
 $ q1     : num  5 3 3 3 2
 $ q2     : num  4 5 5 3 2
 $ q3     : num  5 2 5 4 1
 $ q4     : num  5 5 5 NA 2
 $ q5     : num  5 5 2 NA 1
leadership<-data.frame(manager,data,country,gender,age,q1,q2,q3,q4,q5,stringsAsFactors = FALSE)
> str(leadership)
'data.frame':	5 obs. of  10 variables:
 $ manager: num  1 2 3 4 5
 $ data   : chr  "10/24/08" "10/28/08" "10/1/08" "10/12/08" ...
 $ country: chr  "US" "US" "UK" "UK" ...
 $ gender : chr  "M" "F" "F" "M" ...
 $ age    : num  32 45 25 39 99
 $ q1     : num  5 3 3 3 2
 $ q2     : num  4 5 5 3 2
 $ q3     : num  5 2 5 4 1
 $ q4     : num  5 5 5 NA 2
 $ q5     : num  5 5 2 NA 1

变量的重编码

数据中q4,q5列中有缺失值,以后在进行统计的过程中要对NA进行处理要么进行替换要么进行忽略。
如果我想把age下的数据进行分组,并且改为类别型变量如agecat(young,middle aged,elder),再进行分组前我们首先要把99岁的年龄值定位NA,这里主要是因为不符合实际。

> leadership$age[leadership$age==99]<-NA
> leadership
  manager     data country gender age q1 q2 q3 q4 q5
1       1 10/24/08      US      M  32  5  4  5  5  5
2       2 10/28/08      US      F  45  3  5  2  5  5
3       3  10/1/08      UK      F  25  3  5  5  5  2
4       4 10/12/08      UK      M  39  3  3  4 NA NA
5       5   5/1/09      UK      F  NA  2  2  1  2  1

下面我们创建agecat变量

> leadership$agecat[leadership$age>75]<-"Elder"
> leadership$agecat[leadership$age>=55&leadership$age<=75]<-"middle aged"
> leadership$agecat[leadership$age<55]<-"Young"
> leadership
  manager     data country gender age q1 q2 q3 q4 q5 agecat
1       1 10/24/08      US      M  32  5  4  5  5  5  Young
2       2 10/28/08      US      F  45  3  5  2  5  5  Young
3       3  10/1/08      UK      F  25  3  5  5  5  2  Young
4       4 10/12/08      UK      M  39  3  3  4 NA NA  Young
5       5   5/1/09      UK      F  NA  2  2  1  2  1   <NA>

当然你可以使用within函数进行简化,用法如with函数。

> leadership<-within(leadership,{
+     age<-NA
+     agecat[age>75]<-"elder"
+     agecat[age>=55&age<=75]<-"middle aged"
+     agecat[age<55]<-"young"
+ })
> leadership
  manager     data country gender age q1 q2 q3 q4 q5 agecat
1       1 10/24/08      US      M  NA  5  4  5  5  5  Young
2       2 10/28/08      US      F  NA  3  5  2  5  5  Young
3       3  10/1/08      UK      F  NA  3  5  5  5  2  Young
4       4 10/12/08      UK      M  NA  3  3  4 NA NA  Young
5       5   5/1/09      UK      F  NA  2  2  1  2  1   <NA>

还有一些其他的方法可以实现重编吗,如car包中的recode函数

recode(var, recodes, as.factor.result, as.numeric.result=TRUE, levels)
var为一个数值向量,recodes为重编码的规则。
> x<-c(1:10)
> x
 [1]  1  2  3  4  5  6  7  8  9 10
> recode(x,"1:3='C';4:6='B';7:9='A';else='NULL'")
 [1] "C"    "C"    "C"    "B"    "B"    "B"    "A"    "A"    "A"    "NULL"

变量的重命名

names(leadership)[2]<-'testDate'
names(leadership)[6:10]<-c("item1","item2","item3","item4","item5")
> leadership
  manager testDate country gender age item1 item2 item3 item4 item5 agecat
1       1 10/24/08      US      M  NA     5     4     5     5     5  Young
2       2 10/28/08      US      F  NA     3     5     2     5     5  Young
3       3  10/1/08      UK      F  NA     3     5     5     5     2  Young
4       4 10/12/08      UK      M  NA     3     3     4    NA    NA  Young
5       5   5/1/09      UK      F  NA     2     2     1     2     1   <NA>

当然也可以使用plyr包中的rename()函数

缺失值的处理

is.na()用来检测是否存在缺失值
> y<-c(1,2,3,NA)
> is.na(y)
[1] FALSE FALSE FALSE  TRUE

在分析过程中排除NA,这里用到的函数为na.rm=TRUE

> y
[1]  1  2  3 NA
> sum(y,na.rm = TRUE)
[1] 6
>

删除所有含有NA的观测,使用到的函数为na.omit()

> na.omit(leadership)
  manager     data country gender age q1 q2 q3 q4 q5
1       1 10/24/08      US      M  32  5  4  5  5  5
2       2 10/28/08      US      F  45  3  5  2  5  5
3       3  10/1/08      UK      F  25  3  5  5  5  2
5       5   5/1/09      UK      F  99  2  2  1  2  1

注意:行表示观测,列表是变量
将日期转换为字符型变量,以便进行处理如(提取子集,替换,连接)
函数为as.character()
补充:常见的类型转换函数

  1. as.numeric()
  2. as.character()
  3. as.vector()
  4. as.matrix()
  5. as.data.frame()
  6. as.factor()
  7. as.logical()

数据排序

使用order函数进行排序

> with(leadership,{
+     newdata<<-leadership[order(gender,age),]
+ })
> newdata
  manager     data country gender age q1 q2 q3 q4 q5
3       3  10/1/08      UK      F  25  3  5  5  5  2
2       2 10/28/08      US      F  45  3  5  2  5  5
5       5   5/1/09      UK      F  99  2  2  1  2  1
1       1 10/24/08      US      M  32  5  4  5  5  5
4       4 10/12/08      UK      M  39  3  3  4 NA NA

当然你也可以使用attach()函数来代替with()函数

attach(leadership)
newdata<-leadership[order(gender,age),]
detach(leadership)
> newdata
  manager     data country gender age q1 q2 q3 q4 q5
3       3  10/1/08      UK      F  25  3  5  5  5  2
2       2 10/28/08      US      F  45  3  5  2  5  5
5       5   5/1/09      UK      F  99  2  2  1  2  1
1       1 10/24/08      US      M  32  5  4  5  5  5
4       4 10/12/08      UK      M  39  3  3  4 NA NA

数据集的合并
如果要横向合并两个矩阵或者数据框可以使用 merge()函数,或者使用cbind(),通常情况下两个数据框是通过一个或多个共有变量来进行连接的
纵向合并的话使用rbind()

total<-merge(datafraame1,dataframe2,by="id)
1和2按照id进行合并

选入数据

这里的话不要忘记逗号,选取一到三行,不考虑列

> newdata<-leadership[1:3,]
> newdata
  manager     data country gender age q1 q2 q3 q4 q5
1       1 10/24/08      US      M  32  5  4  5  5  5
2       2 10/28/08      US      F  45  3  5  2  5  5
3       3  10/1/08      UK      F  25  3  5  5  5  2

选入大于30岁的男性,代码用&连接

> with(leadership,{
+     newdatas<<-leadership[gender=="F" & age>30,]
+ })
> newdatas
  manager     data country gender age q1 q2 q3 q4 q5
2       2 10/28/08      US      F  45  3  5  2  5  5
5       5   5/1/09      UK      F  99  2  2  1  2  1

可以使用subset()函数简化过程

> newdata5<-subset(leadership,age>35 | age<24,select = c(q1,q2,q3,q4))
> newdata5
  q1 q2 q3 q4
2  3  5  2  5
4  3  3  4 NA
5  2  2  1  2

数据的提取

# 创建一个向量
> vector_2 <- c(1:10)
> vector_2
 [1]  1  2  3  4  5  6  7  8  9 10
 
# 让我们提取第1个数据,注意 R 是以 1 开头的,而不是以 0 开头的。
> vector_2[1]
[1] 1

# 提取第2,3,4个数据
> vector_2[2:4]
[1] 2 3 4

# 提取第2,5个数据
> vector_2[2,5]
Error in vector_2[2, 5] : incorrect number of dimensions
> vector_2[c(2,5)]
[1] 2 5

还可以使用which函数

> h<-c(5,6,8,9,8,99,78)
> h
[1]  5  6  8  9  8 99 78
> which(h<10)
[1] 1 2 3 4 5
> v<-h[which(h<10)]
> v
[1] 5 6 8 9 8

数据的清洗

长宽数据的转换
主要使用tidyr包中的gather()函数
gather函数可以实现长宽数据的转换,因为宽数据的方差分析以及回归分析中不能被识别
宽数据就是每一列就是不同的处理,然后下面是数,而长数据每一行是一个观测,列是变量名

宽数据 
  control   low middle  high
1   20.79 22.22  28.56 31.93
2   22.91 24.74  28.67 37.94
3   27.21 21.53  25.28 39.76
4   19.34 19.66  30.28 27.94
5   17.85 25.89  23.13 29.65
6   23.79 29.10  23.47 34.23
长数据  环境和种子都是变量都会都产量产生影响
  yield seed
1   383    1
2   406    1
3   351    1
4   400    1
5   390    1
6   361    1

先构建一个数据框

> library(tidyr)
> stu<-data.frame(grade=c("A","B","C","D","E"), female=c(5, 4, 1, 2, 3), male=c(1, 2, 3, 4, 5))
> stu
  grade female male
1     A      5    1
2     B      4    2
3     C      1    3
4     D      2    4
5     E      3    5

gather(data, key, value, …, na.rm = FALSE, convert = FALSE)
data:需要被转换的宽形表
key:将原数据框中的所有列赋给一个新变量key
value:将原数据框中的所有值赋给一个新变量value
…:可以指定哪些列聚到同一列中

> widedata <- data.frame(person=c('Alex','Bob','Cathy'),grade=c(2,3,4),score=c(78,89,88))
> widedata
  person grade score
1   Alex     2    78
2    Bob     3    89
3  Cathy     4    88
> longdata <- gather(widedata, variable, value,-person)
> longdata
  person variable value
1   Alex    grade     2
2    Bob    grade     3
3  Cathy    grade     4
4   Alex    score    78
5    Bob    score    89
6  Cathy    score    88