小白读《R语言实战》写的读书笔记(第三章)

#####第三章:基本数据管理#####
####一、一个示例####
#书中建立了一个5行10列的数据框,标题为领导行为的性别差异,具体输入代码如下:
leadership <- data.frame(
  manager = c(1,2,3,4,5),
  date = c("10/24/14", "10/28/14", "10/01/14", "10/12/14", "05/01/14"),
  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,3,5,4,1),
  q4 = c(5,5,5,NA,2),
  q5 = c(5,5,2,NA,1)
)
leadership
#rm(leadership)
#以上数据框为下面章节数据前提


####二、创建新变量####
#基本的表达式为: 变量名 <- 表达式
#基本的加减乘除即+-*/,还有求幂^或者**
#x%%y:求余,例5%%2=1
#x%/%y:整数除法,例5%/%2=2
#以leadership数据框的数据的数据为基础,建立两个新的变量:
total_score <- q1+q2+q3+q4+q5
mean_score <- (q1+q2+q3+q4+q5)/5
#以上这两行代码为错误代码,因为R并不知道q1到q5来自数据框leadership
total_score <- leadership$q1 + leadership$q2 + leadership$q3 + leadership$q4 + leadership$q5
mean_score <- (leadership$q1 + leadership$q2 + leadership$q3 + leadership$q4 + leadership$q5)/5
#这样就新建了两个新的变量
#但这两个是独立变量,并没有合并到leadership数据框中
#利用transform()函数将建立两个新的变量并导入到原leadership数据框中:
leadership <- transform(leadership, 
                        total_score = q1 + q2 + q3 + q4 + q5,
                        mean_score = (q1 + q2 + q3 + q4 + q5)/5)
leadership
#网上还有另外一种方法
leadership$total_score <- leadership$q1 + leadership$q2 + leadership$q3 + leadership$q4 + leadership$q5
leadership$mean_score <- (leadership$q1 + leadership$q2 + leadership$q3 + leadership$q4 + leadership$q5)/5
leadership
##我试验了一下,两种方法都可以

####三、变量的重新编码####
#变量的重新编码就是用旧变量值创建新值的过程,主要用于:
#1、将连续型变量修改为类别值(John注:分类变量)
#2、将错误编码替换为正确值
#3、基于一个分数线创建不同分组变量
#常见逻辑运算符见书46页:
#<小于;>大于;<=小于或等于;>=大于或等于;==严格等于;!=不等于;
#!x 非x;x|y x或y;x&y x和y;isTRUE(x) 测试x是否为TRUE
##现在将leadership数据框中age列重新编码为agecat
#首先将99岁重新正确编码
leadership$age[leadership$age == 99] <- NA
#语句variable[condition] <- expression只有在condition值为TRUE时执行赋值
leadership$agecat[leadership$age > 75] <- "Elder"
leadership$agecat[leadership$age >= 55 & leadership$age <= 75] <- "Middle Aged"
leadership$agecat[leadership$age < 55] <- "Young"
leadership["agecat"]
leadership$agecat #运行这段代码和上一行代码,看看两个有什么不一样
#这里可以用within()函数简化代码
leadership <- within(leadership,{
  agecat <- NA #先创建agecat变量
  age[age == 99] <- NA
  agecat[age > 75] <- "Elder"
  agecat[age >= 55 & age <= 75] <- "Middle Aged"
  agecat[age < 55] <- "young"})
leadership["agecat"]
rm(leadership)
#car包中的recode()函数也可以重编码数据,后续可以自学以下
#上一章学习过within()函数,如果忘了可以回去复习以下


####变量的重命名####
#对于变量名的改变有两种方法
#第一种是利用fix函数调用编辑器,代码如下:
fix(leadership) #这个函数和上一章中手动输入数据是一样的,既可以更改变量名,又可以改动或添加数据
#代码改变量名如下:
names(leadership)
names(leadership)[2] <- "testDate"
leadership
#类似的代码如下:
names(leadership)[6:10] <- c("item1", "item2", "item3", "item4", "item5")


####四、缺失值####
#R中允许缺失值的出现,用NA表示,用is.na()来查找缺失值
#例:
y <- c(1,2,3,NA)
is.na(y)
#不是缺失值返回FALSE,缺失值返回TRUE
is.na(leadership[,6:10])
#对于缺失值有两个重要点:
#1、缺失值是不可比较是
#2、R并不会把无限或者不可能出现的数标记成缺失值:Inf和-Inf为正无穷和负无穷,NaN标记不可能的数,若要识别这些数值,需要用到is.infinite()或is.nan()函数
####以上这两段话说明R中存在3种特别的变量值:缺失值NA,无穷数Inf和不可能的数NaN
###4.1重新编码异常值为缺失值###
#leadership中年龄为99重新编码为NA,
leadership$age[leadership$age == 99] <- NA # = 为赋值;==为强制等于
####4.2在分析中排除缺失值####
#确定了缺失值后,进一步分析前需要删除这些缺失值
#书中定义了代码:
x <- c(1,2,NA,3)
y <- x[1] + x[2] + x[3] + x[4]
z <- sum(x)
y
z
#如果直接计算,y和z都是缺失值
#许多函数都有一个na.rm=TRUE选项用于移除缺失值
y <- sum(x, na.rm = T)
y
#在处理函数中有缺失值时,一定要阅读该函数的帮助文档,检查该函数是如何处理缺失值的
#函数na.omit()可以移除含有缺失值的行:
#这里以上文输入的leadership为例
leadership
newdata <- na.omit(leadership) #这里删除的是含有NA的整行数据
newdata
#这样,所有含有缺失值的行均被删除


####五、日期值####
###R中用as.Date()函数输入日期变量
#R中的日期是可以计算的,并非只是表示为日期格式的字符型数据
#表达式是as.Date(x, "input_format"),其中x是字符型数据,input_format是给定的日期格式
#R中是先输入字符型数据,再让R按照日期格式读取为日期值
#以下是日期格式示例的数据框,我自己做的数据框,内容来自书第50页
符号 <- c("%d", "%a", "%A", "%m", "%b", "%B", "%y", "%Y")
含义 <- c("数字表示日期(0-31)", "缩写的星期名", "非缩写的星期名", "月份(01-12)", "缩写的月份", "非缩写的月份", "两位数的年份", "四位数的年份")
示例 <- c("01-31", "Mon", "Monday", "00-12", "Jan", "January", "07", "2007")
Date_input_foramt <- data.frame(符号, 含义, 示例)
Date_input_foramt
#日期的默认输入格式是:yyyy-mm-dd:
mydate <- as.Date(c("2007-06-22", "2004-02-13"))
mydate
#还可以转换日期格式为mm/dd/yyyy
strDates <- c("01/05/1965", "08/16/1975")
dates <- as.Date(strDates, "%m/%d/%Y")
dates
#在leadership数据框中,日期是以mm/dd/yy的编码格式的字符型变量,现转换为日期值:
leadership$date <- as.Date(leadership$date, "%m/%d/%y")
leadership
##另外Sys.Date()可以返回当天时间
Sys.Date()
#date()返回当天日期及时间
date()
##用format(x, format="output_format")来输出指定格式的日期值
today <- Sys.Date()
format(today, format = "%B %d %Y")
today
format(today, format = "%A")
#R可以储存日期参数作为计算
startdate <- as.Date("2020-02-13")
enddate <- as.Date("2021-01-12")
days <- enddate - startdate
days
#另外可以用difftime()函数来计算时间间隔:
today <- Sys.Date()
dob <- as.Date("1956-10-22")
difftime(today, dob, units = "weeks")  #这里unit可以使用的参数有“auto”, “secs”, “mins”, “hours”, “days”, “weeks”
##将日期转变为字符型变量可以用函数as.character():
strDates <- as.character(dates)
strDates
##以下是时间和日期的帮助文件
help("as.Date")
help("strftime")
help("ISOdatetime")
#如果要对时间进行运算,可以用timeDate包
install.packages("timeDate")
library(timeDate)


####六、类型转换####
##R中有判断数据类型的函数,有改变数据类型的函数
#判断数据类型函数如下
is.numeric()
is.character()
is.vector()
is.matrix()
is.data.frame()
is.factor()
is.logical()
#以上函数返回结果仅仅为TRUE或FALSE
#对应的转换数据类型的函数如下
as.numeric()
as.character()
as.vector()
as.matrix()
as.data.frame()
as.factor()
as.logical()
#以下为书中演示代码
a <- c(1,2,3)
a
is.numeric(a)
is.vector(a)
a <- as.character(a)
a
is.numeric(a)
is.vector(a)
is.character(a)
#以上数据类型的判断与转换将在第5章再次介绍

####七、数据集的排序与合并####
##1.数据的排序##
#用order()函数对一个数据框进行排序,order()为默认升序,-order()为降序
#书中用leadership数据进行演示
newdata <- leadership[order(leadership$age),]
newdata
#以上代码按照经理人年龄升序排序
newdata2 <- leadership[order(leadership$gender, leadership$age),]
newdata2
#以上代码依照女性到男性排序,在性别内部按照升序排序
newdata3 <- leadership[order(leadership$gender, -leadership$age),]
newdata3
#以上代码依照女性到男性排序,在性别内部按照降序排序
###以下为John注
#order()函数如果为了实现排序,切记后面有个",",不然无法实现
#从网上看order()函数实际上是在对变量数据位置进行排序,但并未改变数据位置
#代码举例如下
order(leadership$age)
order(leadership$gender, leadership$age)
order(leadership$gender, -leadership$age)
#order()函数内指令decreasing = T为降序
order(leadership$age, decreasing = T)
#如果要实现代码的直接排序可以用以下代码
leadership[order(leadership$age),]  

##2.数据的合并##
#合并分为添加列(变量)和添加行两种(观测值):
##合并列是通过一个或多个共有变量进行连结的
#语句如下
total <- merge(dataframeA, dataframeB, by = "ID")
#如果有多个变量则用
total <- merge(dataframeA, dataframeB, by = c("ID", "Country"))
#如果直接合并两个矩阵或者数据库,且不需要制定公共索引,则用cbind()函数:
total <- cbind(A, B)
#cbind()函数中各个对象必须拥有相同的行数,且排序顺序相同

##添加行用rbind()函数,语句如下:
total <- rbind(dataframeA, dataframeB)
#两个数据框必须拥有相同的变量,不过顺序不必相同
#但如果一个数据框中有另外一个不存在的数据,必须先做处理
#可以删除多余变量,或者在另外的数据框中添加NA,让二者保持一致

####八、切分数据集####
##选取变量##
#用data.frame[row indices, column indices]来访问数据
newdata4 <- leadership[,c(6:10)]
newdata4
#或选取列名,这样就不用在前方行名留空了[,]
vars <- c("q1", "q2", "q3", "q4", "q5")
newdata5 <- leadership[,vars]
newdata5
#如果只提供了一组要提取的数据,即没有",",R默认提取列,所以下面的代码得出和上面同样的结果
newdata5 <- leadership[vars]
newdata5
#最后用paste()函数可以得出同样的结论,这个函数第5章会细讲
myvars <- paste("q", 1:5, sep = "")
newdata6 <- leadership[myvars]
newdata6
#R中可以不用赋值直接得出结果
myvars <- paste("q", 1:5, sep = "")
leadership[myvars]

##★★★选入和剔除变量对于数据的后续处理相当重要##
##剔除变量##
#剔除变量的代码如下(以leadership数据为例):
myvars2 <- names(leadership) %in% c("q3", "q4") 
newdata7 <- leadership[!myvars2] #注:这里是方括号
newdata7
##以下是语句的解释
#names(leadership)是生成了一个包含所有变量名的字符型向量:即c( "manager" "date"    "country" "gender"  "age"     "q1"      "q2"      "q3"      "q4"      "q5")
#names(leadership) %in% c("q3", "q4") 则返回了一个逻辑型变量,意义是在names(leadership)中q3和q4为TRUE,其余为FALSE
#运算符非(!)将运算符转换:
#最后的语句相当于下面的代码后赋值:
leadership[c(TRUE,TRUE,TRUE,TRUE,TRUE,TRUE, FALSE, FALSE, TRUE)]
#如果知道q3和q4的位置是第8和第9列,可以用以下的代码
newdata8 <- leadership[c(-8,-9)]
newdata8
#或者可以将不需要的列直接丢弃,这样会在最初的数据框中体现:
leadership$q3 <- leadership$q4 <- NULL
leadership

##选入观测值##
#以下是书中选择的代码
newdata9 <- leadership[1:3,] #选取第1行到第3行
newdata9
newdata10 <- leadership[leadership$gender == "M" & leadership$age > 30,] #选择性别为M同时年龄大于30
newdata10
#如果要选择时间限定在2009年1月1日到2009年12月31日的,应该用以下代码“
leadership$date <- as.Date(leadership$date, "%m/%d/%y") ##将leadership中日期由字符型转换成日期型
startdate <- as.Date("2009-01-01")#设定开始与结束时间
enddate <- as.Date("2009-12-31")
newdata11 <- leadership[which(leadership$date >= startdate & leadership$date <= enddate),]#选择时间范围内的数据,切记不要忘了后面的逗号
newdata11##这里的开始与结束时间与前文中leadership的时间不一致,所以结果中无数据


##subset()函数##
##subset()函数是选择变量最简单的方法
newdata12 <- subset(leadership, age >= 35 | age < 23, select = c(q1,q2,q3,q4))
newdata12
#语句解释:选择leadership中年龄大于等于35或小于23的数据,并保留q1,q2,q3,q4数据
newdata13 <- subset(leadership, gender == "M" & age > 25, select = gender:q4)
newdata13
#语句解释:选择leadership数据中性别为M且年龄大于25的数据,并保留gender到q4列

##随机抽样##
#以下语句随机选取leadership数据框中抽取一个大小为3的样本:
mysample <- leadership[sample(1:nrow(leadership), 3, replace = FALSE),]
mysample
#sample()函数的第一个参数是由一个要从中抽样的元素组成的向量:这里是1到数据框中观测值的数量
#帮助文档中指的是要选取文件中的包含一个或多个元素的向量(是否表示抽样的范围?John注)
#第二个参数是要抽取的元素数量,即抽取的样本包含几组数据
#第三个参数表示是否需要放回样本,FASLE表示不放回
##R中有许多抽样工具,根据不同的抽样方法,后面会再次讲到

####九、使用dplyr包操作数据框####
install.packages("dplyr")

##前文中的所有方法均是R中最基本的数据处理方法
##dplyr包提供了许多更加方便的处理函数
#以下为dplyr包基本的函数
select() #选择变量或列(单纯的选择列)
filter() #选择观测值或行(选择满足某些条件的行)
mutate() #转换或重编码变量
rename() #重命名变量或列
recode() #重编码变量值
arrange() #按变量值对行进行排序
##以下重新输入leadership数据
rm(leadership)
leadership <- data.frame(
  manager = c(1,2,3,4,5),
  date = c("10/24/14", "10/28/14", "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 #这里的数据和最初建立的略有出入(John注)
library(dplyr)
leadership <- mutate(leadership, 
                     total_score = q1 + q2 + q3 + q4 + q5,
                     mean_score = total_score/5)
leadership$gender <- recode(leadership$gender, "M" = "male", "F" = "female")
leadership <- rename(leadership, ID = "manager", sex = "gender")
leadership <- arrange(leadership, sex, total_score)
leadership_ratings <- select(leadership, ID, mean_score) #select选择列
leadership_men_high <- filter(leadership, sex == "male" & total_score > 10)#filter选测行
leadership
leadership$total_score
leadership$mean_score
leadership_ratings
leadership_men_high
##现在开始解读代码,⊙﹏⊙b汗
##首先加载dplyr包,用mutate()函数创建两个列,分别是总分和平均分。
#语句是:dataframe <- mutate(dataframe, newver1 = expression, newver2 = expression, ...)
#这样新变量就添加到数据框中了
#下一步是使用recode()函数修改gender的值,格式如下:
#vector <- tecode(vector, oldvalue1 = newvalue1, oldvalue2 = newvalue2, ...)
#这个函数可以改变原有的变量,但未指定的变量值保持不变,例如:
x <- c("a", "b", "c")
x <- recode(x, "a" = "apple", "b" = "banana")
x
#对于数值型变量,需要使用反引号来读取原始值,例如:
y <- c(1,2,3)
y <- recode(y, '1' = 10, '2' = 15)
y
#下一步使用rename()函数来变更变量名,语句如下:
#dataframe <- rename(dataframe, newname1 = "oldname1", newname2 = "oldname2", ...)
#再之后使用函数arrange()对数据进行排序,语序是:
#dataframe <- arrange(dataframe, order1, order2, ...)
#如果需要使用降序,则用desc(),语序如下:
#dataframe <- arrange(dataframe, order1, desc(order2))
#排序的先后顺序以函数中出现条件的先后顺序为准
#函数select()用来选取列(或剔除其他列)
#函数filter()用来选取行(或剔除其他行)
#select()函数语序如下:
#dataframe <- select(dataframe, variablelist1, variablelist2, ...)
#注意,变量名不带引号
#用冒号可以选择一些列变量名,另外可以用函数选择包含特定字符串的变量,例如:
leadership_subset <- select(leadership, ID, country:age, starts_with("q"))
leadership_subset
#根据以上代码选取变量名为 ID,country,sex,age,q1,q2,q3,q4,q5的列
#具体可参阅:
help("select_helpers")
#另外可以用减号-剔除变量,例如:
leadership_subset <- select(leadership, -sex, -age)
leadership_subset
#剔除了sex和age变量
#另外filter()函数用于选取满足条件的一组观测值(行),其语句是:
#dataframe <- filter(dataframe, expression)
#如果表达式中为TRUE则予以保留,并且可以使用布尔逻辑运算符,同时可以用圆括号调整优先级
#例:
extreme_men <- filter(leadership, sex == "male" & (mean_score < 2 | mean_score > 4))
extreme_men
##使用管道操作符对语句进行串接
#dplyr包允许用紧凑的格式来编写代码,即使用由magrittr包提供的管道运算符(%>%),来实现
install.packages("magrittr")
library(magrittr)
#以下有三条语句
high_potentials <- filter(leadership, total_score > 10)
high_potentials <- select(high_potentials, ID, country, mean_score)
high_potentials <- arrange(high_potentials, country, mean_score)
high_potentials
#现在用管道运算符来书写
high_potentials2 <- filter(leadership, total_score > 10) %>% 
  select(ID, country, mean_score) %>%
  arrange(country, mean_score)
high_potentials2
#管道运算符%>% 读作THEN,可以将左边的运算结果传递给右边的函数作为第一个参数
#dplyr包还有许多其他的函数,在第5章中会进行讨论


####十、使用SQL语句操作数据框####
#SQL语言我本身不会,而且感觉用不到,先不学了,如果需要再学吧(John注)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值