《R语言实战》day4-基本数据管理

本章内容

 操纵日期和缺失值

 熟悉数据类型的转换

 变量的创建和重编码

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

 选入和丢弃变量

4.2 创建新变量/对现有变量进行变换

变量名<-表达式

将新变量sumx,meanx整合到原始数据框mydata

mydata <- transform(mydata, 
 sumx = x1 + x2, 
 meanx = (x1 + x2)/2) 

4.3 重编码:根据同一个变量和/或其他变量的现有值创建新值的过程

例如:

 将一个连续型变量修改为一组类别值;

 将误编码的值替换为正确值;

 基于一组分数线创建一个表示及格/不及格的变量。

逻辑运算符

 例子1:将经理人的连续型年龄变量age重编码为类别型变量 agecat(Young、 Middle Aged、Elder)。

  • 缺失值处理:将99岁的年龄值重编码为缺失值
leadership$age[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 <- within(leadership,{ 
 agecat <- NA 
 agecat[age > 75] <- "Elder" 
 agecat[age >= 55 & age <= 75] <- "Middle Aged" 
 agecat[age < 55] <- "Young" }) 

函数within()与函数with()类似(见2.2.4节),不同的是它允许你修改数据框

首先,创 建了agecat变量,并将每一行都设为缺失值。

括号中剩下的语句接下来依次执行。请记住agecat 现在只是一个字符型变量

其他小的应用:

  • car包中的recode()函数可以十分 简便地重编码数值型、字符型向量或因子。
  • doBy包提供了另外一个很受欢迎的函数 recodevar()。
  • R中也自带了cut(),可将一个数值型变量按值域切割为多个区间,并返 回一个因子。

 

4.4 变量的重命名

  • fix(leadership)
    • 调用一个交互式的编辑器。然后你单击变量名,然后在弹出的对话框中将其重命名
  • 单个重命名
    • names(leadership)[2] <- "testDate"
  • 批量重命名
    • names(leadership)[6:10] <- c("item1", "item2", "item3", "item4", "item5")
  • plyr包(已装)中有一个rename()函数,可用于修改变量名;plyr (had.co.nz)
    • rename(dataframe, c(oldname="newname", oldname="newname",...))

例子

library(plyr)

leadership <- rename(leadership, c(manager="managerID", date="testDate"))

4.5 缺失值

is.na():检测缺失值是否存在。

  • 例子:is.na(leadership$age):检查age这一列

  • is.na(leadership[,6:10]):批量检查列

需要注意

第一,缺失值被认为是不可比较 的,即便是与缺失值自身的比较。这意味着无法使用比较运算符来检测缺失值是否存在。例如, 逻辑测试myvar == NA的结果永远不会为TRUE。作为替代,你只能使用处理缺失值的函数(如 本节中所述的那些)来识别出R数据对象中的缺失值。

第二,R 并不把无限的或者不可能出现的数值标记成缺失值。再次地,这和其余像SAS之类 类似的程序处理这类数值的方式所不同。正无穷和负无穷分别用Inf和–Inf所标记。因此5/0返 回Inf。不可能的值(比如说,sin(Inf))用NaN符号来标记(not a number,不是一个数)。若 要识别这些数值,你需要用到is.infinite()或is.nan()。

4.5.1将某些值重编码为缺失值

leadership$age[leadership$age == 99] <- NA

4.5.2 在分析中排除缺失值

含有缺失值的算术表达式和函数的计算结果也是缺失值:由于x中的第3个元素是缺失值,所以y和z也都是NA(缺失值)。

x <- c(1, 2, NA, 3) 
y <- x[1] + x[2] + x[3] + x[4] 
z <- sum(x) 

可以在计算之前移除缺失值并使用剩余 值进行计算:

x <- c(1, 2, NA, 3) 
y <- sum(x, na.rm=TRUE) 

在使用函数处理不完整的数据时,请务必查阅它们的帮助文档(例如,help(sum)),检查 这些函数是如何处理缺失数据的。

  • 通过函数na.omit()移除所有含有缺失值的观测na.omit()可以删除所有含有缺失数据的行
    • ​​​​​​​删除所有含有缺失数据的观测(称为行删除,listwise deletion)是处理不完整数据集的若干 手段之一。

4.6  日期值:日期值通常以字符串的形式输入到R中,然后转化为以数值形式存储的日期变量

  • as.Date():来执行这种转换
    • as.Date(x, "input_format")
    • input_format 如下

mydates <- as.Date(c("2007-06-22", "2004-02-13"))


# 先输入日期符合什么读写规则
myformat <- "%m/%d/%y"
# 再告诉R要依照这个读写规则去写入
leadership$date <- as.Date(leadership$date, myformat)

  • Sys.Date()可以返回当天的日期
  • 而date()则返回当前的日期和时间。
  • 使用函数format(x, format="output_format")来输出指定格式的日期值,并且可以提取日期值中的某些部分
> today <- Sys.Date() 
> format(today, format="%B %d %Y") 
[1] "November 27 2014" 
> format(today, format="%A") 
[1] "Thursday" 

# format()函数可接受一个参数(本例中是一个日期)并按某种格式输出结果
  • 这意味着可以在日期值上执行算术运算。比如计算两个日期间的天数
> startdate <- as.Date("2004-02-13") 
> enddate <- as.Date("2011-01-22") 
> days <- enddate - startdate 
> days 
Time difference of 2535 days 

  • difftime()来计算时间间隔,并以星期、天、时、分、秒来表示。

> today <- Sys.Date() 
> dob <- as.Date("1956-10-12") 
> difftime(today, dob, units="weeks")  
Time difference of 3033 weeks

4.6.1 将日期转换为字符型变量:as.character()

  • 字符型数据转换为日期:help(as.Date)和help(strftime)

4.6.2 更多知识

  • 关于日期和时间格式的知识:help(ISOdatetime)
  • 简化日期处理:lubridate包
  • 对日期进行复杂的计算:timeDate包

4.7 类型转换:名为is.datatype()这样的函数返回TRUE或FALSE,而as.datatype()这样的函数则将其 参数转换为对应的类型。

当和第5章中讨论的控制流(如if-then)结合使用时:

is.datatype()这样的函数将成为 一类强大的工具,即允许根据数据的具体类型以不同的方式处理数据。

另外,某些R函数需要接 受某个特定类型(字符型或数值型,矩阵或数据框)的数据,as.datatype()这类函数可以让 你在分析之前先行将数据转换为要求的格式。

例子

> a <- c(1,2,3) 
> a 
[1] 1 2 3 
> is.numeric(a) 
[1] TRUE 
> is.vector(a) 
[1] TRUE 
> a <- as.character(a) 
> a 
[1] "1" "2" "3" 
> is.numeric(a) 
[1] FALSE 
> is.vector(a) 
[1] TRUE 
> is.character(a) 
[1] TRUE 

4.8 数据排序:order()

在R中,可以使用order()函数对一个数据框进行排序。

  • 默认的排序顺序是升序。在排序变量的 前边加一个减号即可得到降序的排序结果

例子

# 创建新数据集,其中按年龄排序
newdata <- leadership[order(leadership$age),] 

# 按女性到男性,同样性别中按年龄排序
attach(leadership) 
newdata <- leadership[order(gender, age),] 
detach(leadership) 

# 按性别和年龄降序排序
attach(leadership) 
newdata <-leadership[order(gender, -age),] 
detach(leadership)

4.9 数据集合并

4.9.1 向数据框添加列:merge();cbind()

total <- merge(dataframeA, dataframeB, by="ID") 

total <- merge(dataframeA, dataframeB, by=c("ID","Country"))

用cbind()进行横向合并
如果要直接横向合并两个矩阵或数据框,并且不需要指定一个公共索引,那么可以直接使
用cbind()函数:


total <- cbind(A, B) 
这个函数将横向合并对象A和对象B。为了让它正常工作,每个对象必须拥有相同的行数,
以同顺序排序。

4.9.2 向数据框添加行:rbind()

纵向合并两个数据框(数据集),请使用rbind()函数:

total <- rbind(dataframeA, dataframeB)

  • 两个数据框必须拥有相同的变量,不过它们的顺序不必一定相同。
  • 如果dataframeA中拥有 dataframeB中没有的变量,请在合并它们之前做以下某种处理:
    • 删除dataframeA中的多余变量;
    •  在dataframeB中创建追加的变量并将其值设为NA(缺失)

4.10 数据集取子集

4.10.1 选入(保留)变量

  • 数据框中的元素是通过dataframe[row indices, column indices]这样的记号
newdata <- leadership[, c(6:10)]

4.10.2 剔除(丢弃)变量

  • 方法1:
myvars <- names(leadership) %in% c("q3", "q4") 
newdata <- leadership[!myvars] 

(1) names(leadership) 生成了一个包含所有变量名的字符型向量: c("managerID","testDate","country","gender","age","q1", "q2","q3","q4","q5")。

(2) names(leadership) %in% c("q3", "q4") 返回了一个逻辑型向量, names(leadership)中每个匹配q3或q4的元素的值为TRUE,反之为FALSE:c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE)。

(3) 运算符非(!)将逻辑值反转:c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE)。

(4) leadership[c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE)]选择了逻辑值为TRUE的列,于是q3和q4被剔除了

  • 方法2

在知道q3和q4是第8个和第9个变量的情况下,可以使用语句:

newdata <- leadership[c(-8,-9)]

将它们剔除。这种方式的工作原理是,在某一列的下标之前加一个减号(–)就会剔除那一列

  • 方法3:

相同的变量删除工作亦可通过: leadership$q3 <- leadership$q4 <- NULL 来完成。

这回你将q3和q4两列设为了未定义(NULL)。注意,NULL与NA(表示缺失)是不 同的。

4.10.3 选入观测

newdata <- leadership[1:3,] 

 newdata <- leadership[leadership$gender=="M" & 
 leadership$age > 30,] 

 attach(leadership) 
 newdata <- leadership[gender=='M' & age > 30,]
 detach(leadership) 

其实就是筛选的过程在 [ ]里完成了,具体的方法和别的一样

希望将研究范围限定在2009年1月1日到2009年12 月31日之间收集的观测上

leadership$date <- as.Date(leadership$date, "%m/%d/%y") 
 startdate <- as.Date("2009-01-01") 
 enddate <- as.Date("2009-10-31")
 newdata <- leadership[which(leadership$date >= startdate &
 leadership$date <= enddate),] 

由于as.Date()函数的默认格式就是yyyy-mm-dd,所以你无需在这里提供这个参数

4.10.4 subset():简单方法

例子

newdata<-subset(leadership,age>=35 | age<24,select=c(q1,q2,q3,q4))

newdata<-subset(leadership,gender=="M" & age>25,select=gender:q4)
  • 选择所有25岁以上的男性,并保留了变量gender 到q4(gender、q4和其间所有列)

4.10.5 随机抽样:sample()

mysample <- leadership[sample(1:nrow(leadership), 3, replace=FALSE),]

sample()函数中:

  • 第一个参数是一个由要从中抽样的元素组成的向量。在这里,这个向量 是1到数据框中观测的数量,
  • 第二个参数是要抽取的元素数量
  • 第三个参数表示无放回抽样。

sample()函数会返回随机抽样得到的元素,之后即可用于选择数据框中的行。

其他

R中拥有齐全的抽样工具,包括抽取和校正调查样本(参见sampling包)以及分析复杂调 查数据(参见survey包)的工具。其他依赖于抽样的方法,包括自助法和重抽样统计方法,详 见第12章。

4.11 使用SQL语句操作数据框:sqldf()

你可以使用sqldf()函数 在数据框上使用SQL中的SELECT语句。

例子:从数据框mtcars中选择所有的变量(列),保留那些使用化油器(carb)的车型(行),按照mpg对车型进行了 升序排序,并将结果保存为数据框newdf。参数row.names=TRUE将原始数据框中的行名延续到了新数据框中

  • sqldf("sql语句",row.names=TRUE)
library(sqldf)
newdf<-sqldf("select * from mtcars where carb=1 order by mpg",row.names = TRUE)
newdf

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值