R语言实战第4章:基本数据管理

第四章

本章内容:

  • 操作日期和缺失值
  • 熟悉数据类型的转换
  • 变量的创建和重编码
  • 数据集的排序、合并与取子集
  • 选入和丢弃变量

4.1 一个示例

新建示例(示例具体含义大家可以看下R语言实战第2版p69):

经理人 日期 国籍 性别 年龄 q1 q2 q3 q4 q5
1 10/24/08 US M 32 5 4 5 5 5
2 10/28/08 US F 45 3 5 2 5 5
3 10/01/08 UK F 25 3 5 5 5 2
4 10/12/08 UK M 39 3 3 4
5 05/01/09 UK F 99 2 2 1 2 1

使用代码创建一个名为leadership的数据框存储上述表格

manager <- c(1,2,3,4,5)
data <- c('10/24/08','10/28/08','10/01/08','10/12/08','05/01/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)

4.2 创建新变量

公式:

变量名 <- 表达式

“表达式”可以包含多种运算符和函数。

给数据框mydata添加两个变量,x1x2之和,x1x2的平均数

mydata <- data.frame(x1 = c(2,2,6,4),
                     x2 = c(3,4,2,8))
# 方法一
mydata$sum <- mydata$x1 + mydata$x2
mydata$mean <- (mydata$x1 + mydata$x2)/2

# 方法二
attach(mydata)
sum <- x1 + x2
mean <- (x1 + x2)/2
detach(mydata)

# 方法三
mydata <- transform(mydata, sum = x1 + x2,
          mean = (x1+x2)/2)

推荐大家使用方法三,简单快捷

4.3 变量的重编码

重编码涉及根据同一变量和或其他变量的现有值创建新值的过程。

不妨假设你希望将leadership数据集中经理人的连续型年龄变量age重编码为类别型变量agecat(Young、 Middle Aged、Elder)。首先,必须将99岁的年龄值重编码为缺失值(因为不可能有人99岁了还当经理,我们默认99是缺失值),使用的代码为:

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

然后用以下代码创建新变量agecat为age的类别型变量

leadership$agecut[leadership$age > 60] <- "Elder"
leadership$agecut[leadership$age >= 40 & 
                  leadership$age <= 60] <- "Middle Aged"
leadership$agecut[leadership$age < 40 ] <- "Young"

当然这个代码看起来很臃肿,可以用函数within()它和with()

类似,不同的就是函数within()可以允许你修改数据。

leadership <- within(leadership,{
                     agecut <- NA
                     agecut[age>60] <- 'Elder'
                     agecut[age>=40 & age<=60] <- 'Middle Aged'
                     agecut[age<40] <- 'Young'
})

此时agecut只是字符型变量,我们需要转换成有序型因子:

leadership$agecut <- factor(leadership$agecut,
                            levels = c('Young','Middle Aged','Elder'),
                            ordered = TRUE)

4.4 变量的重命名

方法一:

names(leadership)[1] <- "ManageID"
names(leadership)[2] <- "testDate"

方法二:使用plyr包中的函数rename()

使用格式:

rename(dataframe,c(oldname = 'newname', oldname = 'newname', ...))
install.packages("plyr") #已经安装了plyr包的略过这一步
library(plyr)
leadership <- rename(leadership,
                     c(manager = "ManageID",
                       date = "testData"))

4.5 缺失值

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

is.na(leadership[,6:10])
##         q1    q2    q3    q4    q5
## [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

检测数据框leadership第6-10列是否有缺失值
注意:

  1. 缺失值被认为是不可比较的。
  2. R并不会把无限的或者不可能出现的标记为缺失值。正无穷和负无穷分别为Inf和-Inf,不可能的值用NaN表示。识别分别用is.infinite()或is.nan()

4.5.1 重编码某些值为缺失值

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

4.5.2 在分析中排除缺失值

很多函数自带参数na.rm = TRUE,可以在计算之前移除缺失值使用剩余值计算

x = c(1,2,NA,4)
sum(x, na.rm = TRUE)

使用函数处理不完整的数据时,查下帮助文档,看看这些函数时如何处理缺失数据的。

na.omit()移除所有含缺失值的观测。

(newdata = na.omit(leadership))
##   ManageID   testData country gender age q1 q2 q3 q4 q5      agecut
## 1        1 2008-10-24      US      M  32  5  4  5  5  5       Young
## 2        2 2008-10-28      US      F  45  3  5  2  5  5 Middle Aged
## 3        3 2008-10-01      UK      F  25  3  5  5  5  2       Young

4.6 日期值

日期值通常以字符串的形式输入到R中,然后转化为以数值形式存储的日期变量。语法as.Data(x, "input_format")

日期格式如下表

符号 含义 示例
%d 数字表示的日期(0~31) 01~31
%a 缩写的星期名 Mon
%A 非缩写星期名 Monday
%m 月份(00~12) 00~12
%b 缩写的月份 Jan
%B 非缩写月份 January
%y 两位数的年份 07
%Y 四位数的年份 2007

日期值默认输入格式为‘yyyy-mm-dd’

Sys.Date() #返回当前日期
## "2021-05-25"

Sys.time() #返回当前日期+时间
## "2021-05-25 16:44:31 CST"

使用format(x, format = "output_format")输出指定格式的日期值或提取日期值的某些部分

today = Sys.Date()
format(today, format = "%d/%m/%y")
## "25/05/21"

format(today, format = "%A")
## "星期二"

既然存储为了数值型数据,那日期是可以进行算术运算的

today = Sys.Date()
my_birth <- as.Date("1996-01-11")
days <- today - my_birth
days
## Time difference of 9266 days

函数difftime()可以来计算时间间隔,并以星期、天、时、分、秒来表示(取决于参数units =)。

difftime(today, my_birth, units = "weeks")
## Time difference of 1323.714 weeks

思考下大家可以知道my_birth这一天是周几吗?

format(my_birth, "%A")
## "星期四"

4.6.1 将日期转换为字符型变量

strdata = as.character(data)

# 举例
as.character(my_birth)
## "1996-01-11"

4.7 类型转换

类型转换函数

判断 转换
is.numeric() as.numeric()
is.character() as.character()
is.vector() as.vector()
is.matrix() as.matrix()
is.data.frame() as.data.frame()
is.factor() as.factor()
is.logical() as.logical()

4.8 数据排序

order()默认升序,在排序变量的前边加一个减号即可得到降序的排序结果。

举例:各行依女性到男性、同样性别中按年龄升序排序。

newdata <- leadership[order(leadership$gender,leadership$age),]

各行依女性到男性、同样性别中按年龄降序排序。

newdata <- leadership[order(leadership$gender, -leadership$age),]

4.9 数据集的合并

方法一:

横向合并两个数据框

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

将dataframeA和dataframeB按ID进行合并。

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

将dataframeA和dataframeB按ID和Country进行合并。

方法二:

cbind()

横向合并,保证其正常工作需:每个对象必须拥有相同的行数、以同顺序排序。

方法三:

rbind()

total = rbind(dataframeA, dataframeB)

4.10 数据集取子集

4.10.1 选入(保留)变量

myvars <- paste0("q",1:5)
newdata <- leadership[myvars]
newdata2 <- leadership[,myvars]

newdata=newdata2保留q1-q5列

4.10.2 剔除(丢弃)变量

方法一:

myvar <- names(leadership) %in% c("q1","q2")
newdata <- leadership[!myvar]
newdata

方法二:只要要删哪一行,直接给出来即可

newdata <- leadership[c(-6,-7)]

方法三:知道要删哪个变量,直接赋值NULL

leadership$q1 = leadership$q2 = NULL

4.10.3 选入观测

举例:选出30岁以上的男性

select1 <- leadership[leadership$gender == 'M' & leadership$age > 30,]

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

min <- as.Date("2009-01-01")
max <- as.Date("2009-12-31")
select2 <- leadership[leadership$data > min & leadership$data < max,]

4.10.4 subset()函数

非常简单的选择变量和观测的方法

select3 <- subset(leadership, age>=35|age<24,
                  select = c(q1:q4))

第一个参数:要进行筛选的数据集

第二个参数:逻辑表达式—表示要留下的行(此处为留下年龄在24-35的人)

第三个参数:要留下的列(此处为留下q1-q4列)

4.10.5 随机抽样

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

在数据挖掘和机械学习中常用。如你可能希望选择两份随机样本,一份用于构建预测模型,另一份用于验证模型的有效性。

小结

1、掌握创建新变量的函数transform(mydata, name1 = value1, name2 = value2, ...)

2、掌握within()with()用法相似,不同点在于可以对变量进行修改。

3、掌握rename(dataframe,c(oldname = 'newname', oldname = 'newname', ...))。对变量重命名。

4、掌握函数merge()和subset()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容