本文章参考整理自:《R语言实战》之 基本数据管理(第四章)
1. 在数据框中创建新变量
先创建个数据框:
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
> mydata
x1 x2 sumx meanx
1 2 2 4 2.0
2 3 5 8 4.0
3 4 7 11 5.5
4 5 9 14 7.0
- 法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. 用
transform()
函数实现:这个在书中的前面章节比较少见,直接用函数把运算打包起来,较上一种方法,完全不需要再引用数据框,它简化了按需创建新变量并保存到数据框的过程。
其中transform()
函数的说明可以参考这里
mydata <- transform(mydata,
sumx = x1 + x2,
meanx = (x1 + x2)/2)
- 法4. 用
winthin()
函数实现:
> mydata <- within(mydata,{x3<-c(3,3,3,3)})
> mydata
x1 x2 sumx meanx x3
1 2 2 4 2.0 3
2 3 5 8 4.0 3
3 4 7 11 5.5 3
4 5 9 14 7.0 3
- 补充:将数据框中的某列删除:(注意观察NULL和NA的不同,前者将该行删除,后者只是将该行值设为空,并未删除该行)
> mydata
x1 x2 sumx meanx
1 2 2 4 2.0
2 3 5 8 4.0
3 4 7 11 5.5
4 5 9 14 7.0
> mydata$sumx <- NULL
> mydata
x1 x2 meanx
1 2 2 2.0
2 3 5 4.0
3 4 7 5.5
4 5 9 7.0
> mydata$meanx <- NA
> mydata
x1 x2 meanx
1 2 2 NA
2 3 5 NA
3 4 7 NA
4 5 9 NA
(1). 也能通过transform()
函数来进行删除:即mydata <- transform(mydata, sumx = NULL, meanx = NULL)
(2). 还能通过winthin()
函数来进行删除:即mydata <- within(mydata,{ sumx <- NULL})
transform()
函数和winthin()
函数可参考这里
2. 变量的重编码和重命名
变量的重编码
即通过原有变量创新值
先创建一个数据框:
> 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) #stringsAsFactors=False说明所有的字符不被转为因子格式
> leadership
manager date 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
重新编码的三种方式:
- 法1. 用
fix(数据框名)
函数,通过弹出的编辑框进行修改,不仅能修改各变量值,还能重命名各变量名。如fix(leadership)
。 - 法2. 通过
变量名[条件] <- 新值
。
leadership$agecat[leadership$age > 75] <- "Elder"
leadership$agecat[leadership$age > 50 & leadership$age <= 75] <- "Middle Aged"
leadership$agecat[leadership$age <= 50] <- "Young"
- 法3. 用
within()
函数实现
> leadership <- within(leadership,{
+ agecat <- NA
+ agecat[age > 75] <- "Elder"
+ agecat[age >= 55 & age <= 75] <- "Middle Aged"
+ agecat[age < 55] <- "Young" })
> leadership
manager date 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 99 2 2 1 2 1 Elder
> leadership <- within(leadership,{
+ age[age > 75] <- "Elder"
+ age[age >= 55 & age <= 75] <- "Middle Aged"
+ age[age < 55] <- "Young" })
> leadership
manager date country gender age q1 q2 q3 q4 q5 agecat
1 1 10/24/08 US M Young 5 4 5 5 5 Young
2 2 10/28/08 US F Young 3 5 2 5 5 Young
3 3 10/1/08 UK F Young 3 5 5 5 2 Young
4 4 10/12/08 UK M Young 3 3 4 NA NA Young
5 5 5/1/09 UK F Elder 2 2 1 2 1 Elder
变量的重命名
三种方式:
- 法1、交互式,在弹出的编辑窗口进行编辑。
fix(leadership)
- 法2、函数
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
- 法3、
plyr包
中的rename()
函数
library(plyr) #先导入这个包
leadership <- rename(leadership,
c(manager="managerID", date="testDate"))
3. 如何处理缺失值
主要从几个方面分析缺失值:缺失值是什么,该如何标记它,如何设置它。遇到缺失值时,怎么排除。
- 1.缺失值:
NA
(not available,不可用) - 2.
is.nan( )
检测缺失值,返回相当大小的对象,元素是逻辑值
> x <- c(1,2,3,NA)
> is.na(x)
[1] FALSE FALSE FALSE TRUE
- 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. 日期值的使用
以字符串性质输入到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] "2019-08-20"
> date()
[1] "Tue Aug 20 11:39:06 2019"
可通过format(x,format="输出格式")
为输出指定日期值和提取日期中的某些部分。
> today <- Sys.Date()
> format(today, format="%B %d %Y")
[1] "八月 20 2019"
> 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 3279.571 weeks
> dob
[1] "1956-10-12"
> today
[1] "2019-08-20"
5. 数据类型的判断及转换
日期转化为字符型变量
strDates<-as.character(dates)
类型判断及转换
向数值型向量添加一个字符串,则此向量所有元素转换为字符型
判断 | 转换 |
---|---|
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() |
6. 数据排序
order()
可对数据框排序,默认升序。在排序变量加减号,变成降序。
- 按年龄升序排序
newdata<-leadership[order(leadership$age),] #注意这个逗号(,)别忘了
- 按年龄降序排序
newdata<-leadership[order(-leadership$age),] #注意这个逗号(,)别忘了
- 先按女性到男性排,同性别中,按年龄升序排
newdata<-leadership[order(leadership$gender,leadership$age),]
或下面那样也可以
attach(leadership)
newdata<-leadership[order(gender,age),]
detach(leadership)
7. 数据集的合并
- 内联结(inner join)(
merge()
)
merge()
函数,
(1)total<- merge(dataframeA, dataframeB,by="ID")
是数据集dataframeA, dataframeB通过ID进行合并
(2)total<- merge(dataframeA, dataframeB,by=c("ID","Country"))
数据集dataframeA, dataframeB按照ID和Country进行合并
例子:
> x <- data.frame(k1 = c(NA,NA,3,4,5), k2 = c(1,NA,NA,4,5), data = 1:5)
> y <- data.frame(k1 = c(NA,2,NA,4,5), k2 = c(NA,NA,3,4,5), data = 1:5)
> z <- merge(x, y, by="k1")
> z
k1 k2.x data.x k2.y data.y
1 4 4 4 4 4
2 5 5 5 5 5
3 NA 1 1 NA 1
4 NA 1 1 3 3
5 NA NA 2 NA 1
6 NA NA 2 3 3
- 横向合并(不需要指定一个公共索引)(
cblind(A,B)
)
total<-cblind(A,B)
横向合并A和B(对象具有相同的行数) - 纵向合并(向数据框添加行)(
rblind(A,B)
)
total<-rblind(dataframeA,dataframeB)
注意: A和B要有相同的对象,也就是列数要相同,但顺序不一定要相同。
8. 数据集取子集
(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
(2)剔除(丢弃)变量
- 法一:
> names(leadership)
[1] "manager" "date" "country" "gender" "age" "q1" "q2" "q3" "q4" "q5"
> names(leadership)%in%c("q3","q4")
[1] FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE
> myvars<-names(leadership)%in%c("q3","q4") #先匹配要剔除的
> !myvars
[1] TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE TRUE
> newdata<-leadership[!myvars] #叹号!是用来反转的
> newdata
manager date country gender age q1 q2 q5
1 1 10/24/08 US M 32 5 4 5
2 2 10/28/08 US F 45 3 5 5
3 3 10/1/08 UK F 25 3 5 2
4 4 10/12/08 UK M 39 3 3 NA
5 5 5/1/09 UK F NA 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列被删除了。
- 法3:设为未定义(NULL,注意NULL与NA不同)
leadership$q3 <- leadership$q4 <- NULL
(3)subset()
函数
参数1:要操作的数据集
参数2:条件
参数3:要选取的列的集合。
- 选择q1、q2、q3、q4列,并且保留的观测是满足年龄在小于24,或大于35的条件下。
ewdata <- subset(leadership, age >= 35 | age < 24,
select=c(q1, q2, q3, q4))
- 选择gender至q4列,并且保留的观测是满足年龄在性别为男,且大于25的条件下。
> newdata <- subset(leadership, gender=="M" & age > 25,
select=gender:q4)
> leadership
manager date 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
> newdata
gender age q1 q2 q3 q4
1 M 32 5 4 5 5
4 M 39 3 3 4 NA
9. 随机抽样函数sample()
sample(从中抽样的数据行数向量,抽样个数,是否放回FALSE为无放回)
格式:sample(n, x, replace=FALSE)
要从n
行数据里以不放回的方式随机抽取x
行,
示例:
mysample <- leadership[sample(1:nrow(leadership),3,replace=FALSE)]
结果:
> 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