《R语言实战》学习笔记:第四章 基本数据管理
基本数据管理
创建新变量
方法一: 直接添加
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, 5, NA, 1)
#创建数据框
leadership <- data.frame(manager, date, country, gender, age,
q1, q2, q3, q4, q5,stringsASFactors = F)
mydata <- data.frame(x1 = c(2, 2, 6, 4), x2 = c(3, 4, 2, 8))
mydata$sumx <- mydata$x1 + mydata$x2
mydata$meanx <- (mydata$x1 + mydata$x2)/2
mydata
#输出
x1 x2 sumx meanx
1 2 3 5 2.5
2 2 4 6 3.0
3 6 2 8 4.0
4 4 8 12 6.0
方法二: 绑定数据框之后、直接添加
attach(mydata)
mydata$sumx <- x1 + x2
mydata$meanx <- (x1 + x2)/2
detach(mydata)
方法三: 使用transform( )函数
mydata <- data.frame(x1 = c(2, 2, 6, 4), x2 = c(3, 4, 2, 8))
transform( ) 函数可以为数据框添加新变量
BOD <- transform(BOD, zimu = c("a","b","c","d","d","f"))
BOD
#输出
Time demand zimu
1 1 8.3 a
2 2 10.3 b
3 3 19.0 c
4 4 16.0 d
5 5 15.6 d
6 7 19.8 f
还可以删除数据框中的变量
test <- transform(BOD, demand = NULL)
test
#输出
Time zimu
1 1 a
2 2 b
3 3 c
4 4 d
5 5 d
6 7 f
变量的重编码
对现有变量进行类型转换、分组等操作
举例:将连续型的年龄变量age,重编码为类别型变量agecat(Young、Middle Aged、Elder)
方法一:
leadership$agecat [leadership$age == 99] <- NA #处理缺失值
leadership$agecat [leadership$age > 75] <- "Elder" #使用逻辑符号进行分组
leadership$agecat [leadership$age >= 55 & leadership$age <= 75] <- "Middle Aged"
leadership$agecat [leadership$age < 55] <- "Young"
leadership
#输出
manager date country gender age q1 q2 q3 q4 q5 stringsASFactors agecat
1 1 10/24/08 US M 32 5 4 5 5 5 FALSE Young
2 2 10/28/08 US F 45 3 5 2 5 5 FALSE Young
3 3 10/1/08 UK F 25 3 5 5 5 5 FALSE Young
4 4 10/12/08 UK M 39 3 3 4 NA NA FALSE Young
5 5 5/1/09 UK F 99 2 2 1 2 1 FALSE Elder
方法二: 使用within( )函数
leadership <- within (leadership, {
agecat <- NA #向数据框中增一列名为agecat,并全部赋值为NA
agecat [age > 75] <- "Elder" # 使用逻辑符号进行分组
agecat [age >= 55 & age <= 75] <- "Middle Aged"
agecat [age < 55] <- "Young" })
within(数据框,{分组条件}) 函数,可以对数据框指定的变量进行分组
变量的重命名
方法一: 使用fix( )函数,打开交互式的编辑器进行修改
fix(leadership)
方法二: 使用names( )函数进行编程
names (leadership) [2] <- "testData"
names (leadership) [6:10] <- c("item1", "item2", "item3", "item4", "item5")
leadership
#输出
manager testData country gender age item1 item2 item3 item4 item5 stringsASFactors agecat
1 1 10/24/08 US M 32 5 4 5 5 5 FALSE Young
2 2 10/28/08 US F 45 3 5 2 5 5 FALSE Young
3 3 10/1/08 UK F 25 3 5 5 5 5 FALSE Young
4 4 10/12/08 UK M 39 3 3 4 NA NA FALSE Young
5 7 5/1/09 UK F 99 2 2 1 2 1 FALSE Elder
函数names(object),可以显示object对象中各成分的名称
x <- names(leadership)
x
#输出
[1] "manager" "testData" "country" "gender"
[5] "age" "item1" "item2" "item3"
[9] "item4" "item5" "stringsASFactors" "agecat"
方法三: 使用plyr包的rename( )函数
library(plyr)
leadership <- rename(leadership, c(manager="managerID", date="testDate"))
plyr包的常用函数
- ddply( ):对数据框进行分组统计
# 对数据框x按照它的var变量进行分组,对每个小组中的数值型变量求中位数
ddply(x, .(var), colwise(median, na.rm = T))
- each( ):把多个函数整合到一个函数中
each(min, max)(x) # 求x向量的最小值和最大值
- colwise( ):把作用于行向量的函数转化为作用于列向量的函数
colwise(median)(x, na.rm = T) #对x向量的每一列求中位数
- arrange( ):对数据框进行排序
arrange(x, desc(var)) # 对数据框x按照它的var变量进行降序排序
-
rename( ):变量的重命名
-
count( ):计数
-
match( ):匹配
-
join( ):连接字符串
缺失值
在R中,缺失值以符号NA(Not Available)表示,字符型和数值型数据使用的缺失值符号是相同的
**is.na( )**函数用来检测缺失值是否存在
is.na(leadership[, 6:10])
item1 item2 item3 item4 item5
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE
3 FALSE FALSE FALSE FALSE FALSE
4 FALSE FALSE FALSE TRUE TRUE
5 FALSE FALSE FALSE FALSE FALSE
注:
- 缺失值是不可比较的,即便是与缺失值自身的比较。例 如,isna(myvar)=TRUE,但是myvar==NA结果为FALSE;
- 无限的(Inf, -Inf,例如5/0将返回Inf)或者不可能出现的(NaN,例如sin(Inf))数值不被标记成缺失值;
- 可以使用赋值语句将某些值重编码为缺失值,例如:leadershipage == 99] <- NA ;
- 常见的排除缺失值的方法:方法1:不计算缺失值;方法2:删除缺失值
方法1:不计算缺失值 ,使用参数na.rm=TRUE
x <- c(1, 2, NA, 3)
y <- x[1] + x[2] + x[3] + x[4] # y的值是NA
z <- sum(x) # z的值是NA
# 如果改写为使用参数na.rm=TRUE
z <- sum(x,na.rm=TRUE) # z的值是6
方法2:删除缺失值,使用函数na.omit( ),删除所有含有缺失数据的行
apply(x, margin, fun) 函数可以实现按行计算,其中x 是计算的数组/矩阵,margin是计算的区域(对于矩阵而言,1代表 按行,2代表按列),fun是计算的函数
日期值
日期值通常以字符串的形式输入到R中
以数值形式存储的日期变量
as.Date (x, “input_format” ),其中,x是字符型的日期数据,input_format给出了用于读入日期的适当格式
%d #数字表示的日期(0-31)
%a #缩写的星期名
%A #非缩写星期名
%m #月份(00-12)
%b #缩写的月份
%B #非缩写月份
%y #两位数的月份
%Y #四位数的年份
mydate <- as.Date( c("01/05/1965", "08/16/1975"),"%m/%d/%Y")
mydate
# 输出
"1965-01-05" "1975-08-16"
当以数值形式存储的日期变量后,可以对日期变量执行算术运算
startdate <- as.Date("2004-02-13")
enddate <- as.Date("2011-01-22")
days <- enddate - startdate
# 输出
days
Time difference of 2535 days
可以以字符形式存储的日期变量
as. character (x)
mydate4 <- as.character(c("2007-06-22", "2004-02-13") )
mydate4
# 输出
"2007-06-22" "2004-02-13"
处理日期值的其它常用函数
- Sys.Date( ):返回当前的日期
date( ):返回当前的日期和时间
Sys.Date( )
# 输出
"2019-05-29"
date()
# 输出
"Wed May 29 23:02:22 2019"
- format (x, format=“output_format”):输出指定格式的日期值
today <- Sys.Date( )
format (today, format="%B %d %Y")
# 输出
"五月 29 2019"
- difftime(time1, time2, tz, units = c(“auto”, “secs”, “mins”, “hours”,“days”, “weeks”)):计算时间间隔
其中,time1和time2是计算时间间隔的2个时间,tz表示时区,units表示返回结果的单位
today <- Sys.Date()
dob <- as.Date("1956-10-12")
difftime(today, dob, units="weeks")
# 输出
Time difference of 3267.714 weeks
时间处理的常用包
lubridate包,包含了许多简化日期处理的函数,可以用于 识别和解析日期—时间数据,抽取日期—时间成分(例如 年份、月份、日期等),以及对日期—时间值进行算术运算
timeDate包,包含了对日期的复杂计算,它提供了大量的日期处理函数,可以同时处理多个时区,并且提供了复杂的历法操作功能,支持工作日、周末以及假期
类型转换
类型判断函数
is.numeric()
is.character()
is.vector()
is.matrix()
is.data.frame()
is.factor()
is.logical()
类型转换函数
as.numeric()
as.character()
as.vector()
as.matrix()
as.data.frame()
as.factor()
as.logical()
举例
a <- c(1, 2, 3)
is.numeric(a)
# 输出
TRUE
is.vector(a)
# 输出
TRUE
a <- as.character(a)
is.numeric(a)
# 输出
FALSE
is.vector(a)
# 输出
TRUE
is.character(a)
# 输出
TRUE
数据排序
使用**order()**函数对数据框按照变量的取值进行排序
默认的排序顺序是升序,在排序变量的前边加一个减号即可得到降序
newdata <- leadership[order(leadership$age),] #按照年龄变量进行升序排序
newdata
# 输出
manager date country gender age q1 q2 q3 q4 q5 stringsASFactors
3 3 10/1/08 UK F 25 3 5 5 5 5 FALSE
1 1 10/24/08 US M 32 5 4 5 5 5 FALSE
4 4 10/12/08 UK M 39 3 3 4 NA NA FALSE
2 2 10/28/08 US F 45 3 5 2 5 5 FALSE
5 5 5/1/09 UK F 99 2 2 1 2 1 FALSE
attach(leadership)
newdata <- leadership[order(gender, age),] #先按性别,再按年龄,进行升序排序
detach(leadership)
newdata
# 输出
manager date country gender age q1 q2 q3 q4 q5 stringsASFactors
3 3 10/1/08 UK F 25 3 5 5 5 5 FALSE
2 2 10/28/08 US F 45 3 5 2 5 5 FALSE
5 5 5/1/09 UK F 99 2 2 1 2 1 FALSE
1 1 10/24/08 US M 32 5 4 5 5 5 FALSE
4 4 10/12/08 UK M 39 3 3 4 NA NA FALSE
数据集的合并
将2个数据框(数据集)进行横向(增加列,即增加变量);或者纵向(增加行,即增加观测数据)的合并
横向合并
merge() 函数:2个数据框有相同的变量
# 数据框dataframeA和dataframeB按照变量ID进行合并
total <- merge(dataframeA, dataframeB, by=“ID”)
cbind( ) 函数:2个数据框没有相同的变量,此时2个数据框必须拥有相同的行数,以进行同顺序排序
total <- cbind(dataframeA, dataframeB)
纵向合并
rbind() 函数:2个数据框必须拥有相同的列数(变量数),不过变量顺序不必一定相同
total <- rbind(dataframeA, dataframeB)
如果dataframeA中拥有dataframeB中没有的变量,在合并之前可以做以下处理
-
删除dataframeA中的多余变量
-
在dataframeB中创建追加的变量并将其值设为NA(缺失)
数据集取子集
选取某些变量构成子集
从一个大数据集中选择若干变量来创建一个新的数据集
法一:
newdata <- leadership[, c(6:10)]
法二:
myvars <- c("q1", "q2", "q3", "q4", "q5")
newdata <- leadership[myvars]
法三:
myvars <- paste("q", 1:5, sep="")
newdata <- leadership[myvars]
函数 paste(…, sep="") ,用来连接若干字符串,分隔符为sep
paste("x", 1:3, sep="") # 返回值为c("x1", "x2", "x3")
paste("x",1:3, sep="M") # 返回值为c("xM1","xM2" "xM3")
剔除列变量
剔除若干变量来创建一个新的数据集,例如,剔除有很多缺失值的变量
法一:
#names()生成字符型向量,%in%匹配字符“q3”、”q4”,生成逻辑型向量
myvars <- names(leadership) %in% c("q3", "q4")
myvars
#输出
FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE
#逻辑值反转,生成逻辑型向量;选择逻辑值为TRUE的列,剔除掉变量q3、q4
newdata <- leadership[!myvars]
newdata
#输出
manager date country gender age q1 q2 q5 stringsASFactors
1 1 10/24/08 US M 32 5 4 5 FALSE
2 2 10/28/08 US F 45 3 5 5 FALSE
3 3 10/1/08 UK F 25 3 5 5 FALSE
4 4 10/12/08 UK M 39 3 3 NA FALSE
5 5 5/1/09 UK F 99 2 2 1 FALSE
法二:
newdata <- leadership[c(-8,-9)] # 如果知道q3和q4是第8个和第9个变量
法三:
leadership$q3 <- leadership$q4 <- NULL #直接删除2个变量
法四:
newdata <- transform(leadership, q3=NULL, q4=NULL)
运算符%in%,用来判断前面一个向量内的元素是否在后面一个向量中,返回布尔值TRUE或者FALSE
a <- c(1, 3, 13, 43, 43, 4, 34, 3, 4)
b <- c(1, 13, 11, 434, 1)
a %in% b #将返回逻辑型向量
#输出
TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
选择观测行
选择或者剔除若干观测行
newdata1 <- leadership[1:3, ] # 选取前3行观测
newdata1
#输出
manager date country gender age q1 q2 q3 q4 q5 stringsASFactors
1 1 10/24/08 US M 32 5 4 5 5 5 FALSE
2 2 10/28/08 US F 45 3 5 2 5 5 FALSE
3 3 10/1/08 UK F 25 3 5 5 5 5 FALSE
newdata2 <- leadership[ which( leadership$gender == "M" & leadership$age > 30 ), ]
newdata2
#输出
manager date country gender age q1 q2 q3 q4 q5 stringsASFactors
1 1 10/24/08 US M 32 5 4 5 5 5 FALSE
4 4 10/12/08 UK M 39 3 3 4 NA NA FALSE
subset()函数
subset(x, subset, select)函数是选择变量和观测比较简单的方法
其中,x表示选取的对象,subset为表达式(指出要保留的行),select显示要选取的变量列
# 选择所有age值大于等于35或age值小于24的行,保留了变量q1到q4
newdata1 <- subset( leadership, age >= 35 | age < 24, select=c(q1, q2, q3, q4) )
newdata1
#输出
q1 q2 q3 q4
2 3 5 2 5
4 3 3 4 NA
5 2 2 1 2
#选择所有25岁以上男性的观测行,并保留了变量gender到q4(gender、q4和其间所有列)
newdata2 <- subset( leadership, gender=="M" & age > 25, select=gender:q4 )
newdata2
#输出
gender age q1 q2 q3 q4
1 M 32 5 4 5 5
4 M 39 3 3 4 NA
随机抽样
sample(x, size, replace=F, prob=NULL)函数,可以从数据集中(有放回或无放回地)抽取大小为n的随机样本
其中,x为抽样对象,size为抽样数,replace表示是否采用放回抽样,prob表示抽样权重
#从leadership的所有行中,抽取1个大小为3的样本,使用无放回抽样的方式
mysample <- leadership[ sample(1:nrow(leadership), 3, replace=FALSE), ]
mysample
# 输出
manager date country gender age q1 q2 q3 q4 q5 stringsASFactors
3 3 10/1/08 UK F 25 3 5 5 5 5 FALSE
1 1 10/24/08 US M 32 5 4 5 5 5 FALSE
2 2 10/28/08 US F 45 3 5 2 5 5 FALSE