ch04 基本数据管理
基本数据管理
1. 一个示例
manager <- c(1,2,3,4,5)
date <- c("10/24/08","10/28/08","10/1/08","10/12/08","5/1/09")
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,gender,age,q1,q2,q3,q4,q5,
stringsAsFactors=FALSE)
2. 创建新变量
算数运算符
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
# 方法二
attach(mydata)
mydata$sumx <- x1 + x2
mydata$meanx <- (x1 + x2)/2
detach(mydata)
# 方法三
mydata <- transform(mydata,
sumx = x1 + x2,
meanx = (x1 + x2)/2)
3. 变量的重编码
逻辑运算符
将leadership数据集中经理人的连续型年龄变量age重编码为类别型变量 agecat(Young、 Middle Aged、Elder):
# 将99岁的年龄重编码为缺失值
leadership$age[leadership$age == 99] <- NA
# 创建agecat变量
# 方法一:
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" })
函数within()与函数with()类似,不同的是它允许你修改数据框。
若干程序包都提供了实用的变量重编码函数,特别地,car包中的recode()函数可以十分简便地重编码数值型、字符型向量或因子。而doBy包提供了另外一个很受欢迎的函数 recodevar()。最后,R中也自带了cut(),可将一个数值型变量按值域切割为多个区间,并返回一个因子。
4. 变量的重命名
# 方法一:通过调用交互式编辑器更改
fix(leadership)
# 方法二:rename()函数
library(reshape)
leadership <- rename(leadership,
c(manager="managerID", date="testDate"))
# 方法三:names()函数
names(leadership)
names(leadership)[2] <- "testDate"
5. 缺失值
在R中,缺失值以符号NA(Not Available,不可用)表示。不可能出现的值(例如,被0除的结果)通过符号NaN(Not a Number,非数值)来表示。
# 创建NA
y <- c(1, 2, 3, NA)
# 检测缺失值:is.na()
is.na(leadership[, 6:10])
缺失值被认为是不可比较的,即便是与缺失值自身的比较。这意味着无法使用比较运算 符来检测缺失值是否存在。例如,逻辑测试myvar == NA的结果永远不会为TRUE。作为 替代,你只能使用处理缺失值的函数(如本节中所述的那些)来识别出R数据对象中的缺
失值。
5.1 重编码某些值为缺失值
leadership$age[leadership$age == 99] <- NA
5.2 在分析中排除缺失值
# 参数 na.rm=TRUE:在计算之前移除缺失值并使用剩余值进行计算
x <- c(1, 2, NA, 3)
y <- x[1] + x[2] + x[3] + x[4]
z <- sum(x) #x y z都是NA
y <- sum(x, na.rm=TRUE)
# 参数na.omit():移除所有含有缺失值的观测
newdata <- na.omit(leadership)
6. 日期值
日期值通常以字符串的形式输入到R中,然后转化为以数值形式存储的日期变量。函数as.Date()用于执行这种转化。其语法为as.Date(x, “input_format”),其中x是字符型数据,input_format则给出了用于读入日期的适当格式:
# 日期值的默认输入格式为yyyy-mm-dd,以下语句将默认格式的字符型数据转换为了对应日期:
mydates <- as.Date(c("2007-06-22", "2004-02-13"))
# 使用mm/dd/yyy的个数读取数据:
strDates <- c("01/05/1965", "08/16/1975")
dates <- as.Date(strDates, "%m/%d/%Y")
# leadership数据集
myformat <- "%m/%d/%y"
leadership$date <- as.Date(leadership$date, myformat)
# Sys.Date():返回当天的日期
# date():返回当前的日期和时间
Sys.Date()
date()
# format(x, format):输出指定格式的日期值,并可以提取日期中的某些部分
today <- Sys.Date()
format(today, format="%B %d %Y")
R的内部在存储日期时,是使用自1970年1月1日以来的天数表示的,更早的日期则表示为负 数。这意味着可以在日期值上执行算术运算。例如:
startdate <- as.Date("2004-02-12")
enddate <- as.Date("2011-01-22")
days <- enddate - startdate
#显示了2004年2月13日和2011年1月22日之间的天数
将日期转换为字符型变量:
strDates <- as.character(dates)
7. 类型转换
R中提供了一系列用来判断某个对象的数据类型和将其转换为另一种数据类型的函数:
类型准换函数
a <- c(1,2,3)
is.numeric(a)
is.vector(a)
a <- as.character(a)
is.numeric(a)
is.vector(a)
is.character(a)
当和第5章中讨论的控制流(如if-then)结合使用时,is.datatype()这样的函数将成为 一类强大的工具,即允许根据数据的具体类型以不同的方式处理数据。另外,某些R函数需要接 受某个特定类型(字符型或数值型,矩阵或数据框)的数据,as.datatype()这类函数可以让你在分析之前先行将数据转换为要求的格式。
8. 数据排序
在R中,可以使用order()函数对一个数据框进行排序。默认的排序顺序是升序。在排序变量的前边加一个减号即可得到降序的排序结果。以下示例使用leadership演示了数据框的排序。
# 将各行依女性到男性、同样性别中按年龄升序排序
attach(leadership)
newdata <- leadership[order(gender, age),]
detach(leadership)
# 将各行依经理人的性别和年龄降序排序
attach(leadership)
newdata <-leadership[order(gender, -age),]
detach(leadership)
9. 数据集的合并
9.1 添加列
横向合并两个数据框(数据集),请使用merge()函数。在多数情况下,两个数据框是通 过一个或多个共有变量进行联结的(即一种内联结,inner join)。例如:
total <- merge(dataframeA, dataframeB, by=c("ID", "Country"))
类似的横向联结通常用于向数据框中添加变量
9.2 添加行
要纵向合并两个数据框(数据集),请使用rbind()函数:
total <- rbind(dataframeA, dataframeB)
两个数据框必须拥有相同的变量,不过它们的顺序不必一定相同。如果dataframeA中拥有dataframeB中没有的变量,请在合并它们之前做以下某种处理:
①删除dataframe中的多与变量
②在dataframeB中创建追加的变量并将其值设为NA(缺失)
纵向联结通常用于向数据框中添加观测。
10. 数据集取子集
10.1 选入(保留)变量
# 通过索引
newdata <- leadership[, c(6:10)]
# 通过变量名
myvars <- c("q1", "q2", "q3", "q4", "q5")
newdata <-leadership[myvars]
# 与上面代码结果相同
myvars <- paste("q", 1:5, sep="")
newdata <- leadership[myvars]
10.2 剔除(丢弃)变量
~方法一
myvars <- names(leadership) %in% c("q3", "q4")
newdata <- leadership[!myvars]
上述代码剔除了q3和q4,其代码逻辑为:
(1)names(leadership)生成了一个包含所有变量名的字符型向量
(2)names(leadership) %in% c(“q3”, “q4”)返回了一个逻辑型向量,names(leadership)中每个匹配q3或q4的元素的值为TRUE,反之为FALSE
(3)运算符非(!)将逻辑值反转
(4)leadership[c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE,TRUE)]选择了逻辑值为TRUE的列,于是q3和q4被剔除了
在知道q3和q4是第8个和第9个变量的情况下,可以使用以下语句将其剔除:
newdata <- leadership[c(-8, -9)]
~方法二
相同的变量删除工作亦可以通过以下代码来完成:
leadership$q3 <- leadership$q4 <- NULL
将q3和q4两列设为了未定义(NULL)。注意,NULL与NA(表示缺失)是不同的。
10.3 选入观测
# 示例一
newdata <- leadership[1:3,]
# 示例二
newdata <- leadership[leadership$gender=="M" &
leadership$age > 30,]
# 示例三
attach(leadership)
newdata <- leadership[gender=='M' & age > 30,]
detach(leadership)
在第一个示例中,你选择了第1行到第3行(前三个观测)。
在第二个示例中,你选择了所有30岁以上的男性。
第三个示例使用了attach()函数,所以你就不必在变量名前加上数据框名称了
将研究范围限定在2009年1月1日到2009年12 月31日之间收集的观测上,可以使用以下代码:
startdate <- as.Date("2009-01-01")
enddate <- as.Date("2009-10-31")
newdata <- leadership[which(leadership$date >= startdate &
leadership$date <= enddate),]
10.4 subset()函数
使用subset函数可以更加简单方便的选择变量和观测值。两个示例如下:
# 选择所有age值大于等于35或age值小于24的行,保留了变量q1到q4
newdata <- subset(leadership, age >= 35 | age < 24,
select=c(q1, q2, q3, q4))
# 选择了所有25岁以上的男性,并保留了变量gender到q4
newdata <- subset(leadership, gender=="M" & age > 25,
select=gender:q4)
10.5 随机抽样
sample()函数能够让你从数据集中(有放回或无放回地)抽取大小为n的一个随机样本
mysample <- leadership[sample(1:nrow(leadership), 3, replace=FALSE), ]
sample()函数中的第一个参数是一个由要从中抽样的元素组成的向量。在这里,这个向量是1到数据框中观测的数量,第二个参数是要抽取的元素数量,第三个参数表示无放回抽样。sample()函数会返回随机抽样得到的元素,之后即可用于选择数据框中的行。
更进一步
R中拥有齐全的抽样工具,包括抽取和校正调查样本(参见sampling包)以及分析复杂调 查数据(参见survey包)的工具。其他依赖于抽样的方法,包括自助法和重抽样统计方法,详
见第11章。
11. 使用SQL语句操作数据框
library(sqldf)
newdf <- sqldf("select * from mtcars where carb=1 order by mpg",
row.names=TRUE)
newdf
sqldf("select avg(mpg) as avg_mpg, avg(disp) as avg_disp, gear
from mtcars where cyl in (4, 6) group by gear")
上一篇: linux命令大全
下一篇: Linux命令之备份