R语言实战笔记--第四&五章 数据管理
R语言实战笔记–第四&五章 数据管理
标签(空格分隔): R语言
第四、第五章主要涉及数据管理问题的研究与探讨,在我的理解中, 数据管理是一项相当复杂的工作, 因此, 确定一个合适的处理标准并非易事。
为了避免分类带来的复杂性, 我决定统一考虑所有相关问题。
首先构建了一个基于书本实例的数据框架, 并采用了灵活的数据来源策略。(注:Markdown代码与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")
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)
代码解读
得到一个数据框如下:

从表格中可以看出,在数据中存在'月/日/年'格式的日期记录。作为一名中国人,在不知情的情况下就无法容忍这种日期格式的存在。我对此表示强烈不满:在不知道具体格式的前提下如何辨别'01/02/03'这样的记录究竟是何物?对于存在年龄为99的情况(即尚未退休),这似乎是一种异常情况:为何会出现这种情况?此外,在调查问卷中有时会遇到数据未填写的情况(即q4和q5留空),对此我感到无奈之下只能暂时接受或进行后续处理(即修改后接受)。具体情况具体分析:根据需求来决定下一步的操作方式!为了让内容更加连贯,请直接使用敲代码的方式引入本章内容
基本数据管理
定义变量(计算q1与q2及其平均值,并同样处理q2与q3)
可以通过<-操作符直接定义新变量;同时支持基本运算如+-*/;此外,在列表末尾通常会提供总计。
within函数可用来简化数据输入过程;与with不同的是,在within中可重新构造数据框
leadership$q1q2<-leadership$q1+leadership$q2
leadership<-within(leadership,m_q1q2<-(q1+q2)/2)
代码解读
使用transform(数据框对象,新列名1=公式1,新列名2=公式2……)
leadership<-transform(leadership,q2q3=q2+q3,M_q2q3=(q2+q3)/2)
代码解读
变量重编码(替换99岁那家伙,把年龄分组),先替换年龄
leadership$age[leadership$age==99]<-NA
代码解读
然后分组,建立一个新变量来处理分组后的分组类别
leadership<-within(leadership,{
agecat<-NA
agecat[age>55]<-"Elder"
agecat[age>=35 & age<55]<-"Middle Aged"
agecat[age<35]<-"Young"})
代码解读
随后命名为字段名,请注意这是指位于数据框内部的变量名称,在学术语境下也被称为字段名。其一是 reshape 的 rename 方法。
install.packages("reshape")
library(reshape)
leadership<-rename(leadership,c(manager="managerID",date="testDate"))
代码解读
2、names方法(与上述方法等效,选择一个即可)
names(leadership)[1:2]<-c("managerID","testDate")
代码解读
对于缺失值的简明处理方案,在教材中已经有所提及。后续介绍更为巧妙和高效的解决方案。在处理缺失值之前需先识别其存在,在这种情况下我们主要依赖is.na()函数来进行检测工具的设计与实现。
is.na(leadership[,6:10])
代码解读
然后标注缺失值并设置为NA即可。例如,在类似处理年龄数据时的做法就是对变量进行重编码处理。这里不再重复说明。
在很多统计函数中都有na.rm=TRUE这一参数用于排除缺失值,默认情况下不会忽略缺失值。需要注意的是,在某些情况下计算结果会有所不同,请参考相关帮助文档以确定是否需要启用这一参数。
sum(leadership$q4)
代码解读
total <- colSums(leadership_q4, na.rm = TRUE)
移除包含缺失值的数据行并将其结果赋值给一个变量将不再有意义如果不明白这个概念建议回去复习一下基础知识
na.omit(leadership)
代码解读
在查看leadership数据框时发现该数据框中的‘日期’字段当前存储为char类型而非日期类型。因此我们需要告知R系统该字段应被视为_date_。那该如何确定该字段的数据类型的呢?我们可以直接查看附表以获取所需信息。然后我们需参考附表了解具体所需的时间格式信息,在此案例中涉及使用%y(两位数年份)、%m(两位数月份)以及%d(两位数日)三种代码。
leadership$testDate<-as.Date(leadership$testDate,"%m/%d/%y")
代码解读
默认设置为使用YYYY-MM-DD格式的时间序列值。为了使系统正确识别时间字段,请告知您使用的数据库或数据分析工具(如R语言)该特定字段的数据类型,并指定该字段的数据类型。这将使系统能够识别所有后续使用的各种日期表示法(例如DD/MM/YYYY、MMMMDD等)。以下是一些常用的处理这些数据类型的函数:
Sys.Date() #当前日期“yyyy-mm-dd"格式
date() #当前日期时间"%a %b %d %H:%M:%S %Y",虽然有用,但是又是一个奇葩格式,面貌,我目前没有找到怎么把它转换成日期的方式,求大神解释
Sys.time() #当前日期时间"%Y-%m-%d %H:%M:%S CST"
代码解读
数字类型支持日期间的算术操作!需要注意的是,在计算两个不同时间点的时间差时(Difference),其所需参数必须为纯时间(Date)类型而不能包含小时、分钟、秒(Time)的相关信息;若需采用小时、分钟、秒的时间单位来进行计算,则必须调用difftime函数并传递相应的参数进行处理
Sys.Date()-as.Date("2016-12-11")
difftime(Sys.Date(),as.Date("2016-12-11"),units = "mins")
代码解读
关于日期函数的处理存在一个严重的障碍,在中文操作系统中无法直接使用as.POSIXct对'Dec', 'Oct'等月份以及'Wed', 'Thu'等星期进行转换。这是因为当调用format(Sys.time(), "%%a %%A %%m")时会显示出如'Tuesday', 'Wednesday', '12月'这样的结果,并导致as.POSIXct转换失败。解决方案是在执行时间转换前需将R中的日期格式从中文切换至英文(通过调用Sys.setlocale("LC_TIME", "English")),但这会导致无法直接处理像'December'这样的月份名称的问题,请问如何解决?如果遇到这种情况又该如何操作?建议在完成时间设置后重新切换回中文模式(调用Sys.setlocale("LC_TIME", "Chinese"))。
具体信息请参考附表
leadership<-leadership[order(leadership$gender,-leadership$age),]
代码解读
数据整合(cbind,rbind, merge)
选取、删除数据集,以及抽样
leadership[i,j] #选取i行j列的元素
leadership[c(i1:i2),c(j1:j2)] #选取第i1行到i2行,第j1列到j2列的数据
leadership[c("q1","q2","q3")] #选取q1,q2,q3三个变量的数据
leadership[!(names(leadership) %in% c("q3","q4"))] #选取q3,q4两列之外的所有数据
leadership[c(-7,-8)] #和上一句等效,但是需要知道q3,q4是第7,第8个变量
leadership$q3<-leadership$q4<-NULL #和上两句等效,但注意这一句是直接在数据框中修改,而非可以赋值某个对象
leadership[which(!is.na(leadership$age) & leadership$age<40),] #所有年龄不是na及年龄小于40的行,注意,和order一个德性~
subset(leadership,!is.na(age) & age<40,select = names(leadership)) #和上一句等效,select可省略,省略后返回所有变量,也可以使用managerID:agecat返回从managerID到agecat之间的所有变量
leadership[sample(1:nrow(leadership),3,replace = FALSE),] #sample的意思为,从1到leadership的行数这么多个数里面,抽取3个,采取不放回抽样。得到一个向量,leadership[c,]这个就不用说都知道了。
代码解读
采用sqldf包进行数据查询抽检
高级的数据管理包含三个主要环节:第一阶段主要利用数学统计函数和字符处理函数对数据进行操作,并结合优化相关操作以实现对原始数据进行进一步加工;第二阶段是根据需求编写自定义功能模块负责程序流程控制;对于有一定编程基础的朋友,则可以略过细节直接查看代码说明;而对于非技术人员则需要从基础开始逐步学习;第三阶段完成整合与重新组织工作即根据分析结果将各维度的数据按照预设模式重新组织。
第一部分-数据处理
涉及的函数较多,请查看后续提供的函数列表以便进一步了解相关内容。
1、R语言中的随机数生成属于伪随机数算法范畴,在调用时可以通过设置整数值参数来指定种子值以实现结果可重复性功能。
2、正则表达式的学习相对容易掌握,在实践过程中也能快速上手;具体学习资源可参考正则表达式30分钟入门教程以获取详细指导信息。
3、在使用cat函数连接输出对象时,默认会以空格字符进行分隔;如果需要自定义分隔符可以选择相应的参数选项进行配置。
第二部分-自定义函数
以指定名称创建一个自定义函数:f \leftarrow \text{function}(参数1, 参数2 = 默认值 ...) {
其中包含一系列操作指令。
该函数执行完所有操作后会返回指定的对象。
}
随后采用函数f(参数1设为输入参数;参数2设为输入参数或带有缺省值的可选参数)。接着划分控制流程:主要分为循环机制与条件判断两大类。循环机制包括for和while语句两种基本类型。对于for语句而言:其语法形式为for(每个对象∈一堆对象){执行命令集};其中一堆对象可以涵盖各种数据结构如列表等特殊类型数据结构并支持缺省值设置以提高灵活性与实用性。例如在R语言中常见的用法如for(i∈List)print(i),其中你需要将具体的数据列表提供给变量List以便后续操作展开并明确知道该列表包含何种元素与顺序关系等信息。而对于while语句而言:其语法结构为while(条件成立){执行命令集};其中必须包含使循环终止的条件并且该过程必须确保能够实现这一点否则可能导致程序运行出现死循环问题从而影响整体系统稳定性运行效率等关键指标表现表现表现
条件:if、if-else、ifelse、switch
其语法为if(条件成立)时会执行括号内的命令序列;
当条件满足时使用if部分;若不满足则进入else部分会执行命令集2;
而ifelse则是将上述功能合并为一个简化的语句;
switch语句则基于有输出结果的表达式来进行判断并执行相应指令;
具体来说:
switch(具有输出能力的表达式(例如"输出1"、“输出2”、“输出3"))
如果输出1对应执行语句1(若有返回值则返回给switch并继续后续判断);
否则依次检查其他选项直到找到匹配项;
若无匹配结果则直接进入执行语句4;这一步骤的作用类似于检测异常情况并及时响应在每次操作结束后都可以调用scan()函数来捕获键盘输入的内容;如果没有指定参数,则只能接收实数值(输入错误会收到反馈提示可以通过回车键或使用ctrl+Z等方式结束输入操作)。需要注意的是,在多个选项之间必须使用逗号分隔!
fn<-function(a=TRUE){
if(a){print("T")}else{print("F")}
ifelse(a,print("Y"),print("N")
b<-scan("",what="")
print(switch(b,
A="Asuia",
B="Bar",
C="China",
D="Day",
E="En",
message("You type a wrong letter")
))
}
代码解读
这就是函数~
第三部分-整合重构

在实际应用中,在深入理解维度的概念后,请您参考Excel的数据透视表教程来学习相关知识。这样一来就能掌握这两个函数的作用
在数据管理领域中, 第四章构成基础模块, 而第五章则拓展了高级功能. 学习完这两部分内容后, 我们已经初步掌握了其语法体系, 数据处理技术, 数据组织方法以及程序开发框架. 这些内容就算完成了基础学习. 但作为一个统计分析工具, 它的学习才刚刚开始! I'm ready to dive deeper!
各种表格,有兴趣可以收藏一下:
数学运算符
| 符号 | 用途 |
|---|---|
| + | 加 |
| - | 减 |
| * | 乘 |
| / | 除 |
| ^或** | 求幂 |
| x%%y | 求余(x mod y)。5%%2的结果为1 |
| x%/%y | 整数除法。5%/%2的结果为2 |
判断
| 符号 | 用途 | |
|---|---|---|
| < | 小于 | |
| <= | 小于或等于 | |
| > | 大于 | |
| >= | 大于或等于 | |
| == | 严格等于* | |
| != | 不等于 | |
| !x | 非x | |
| x | y | x或y |
| x & y | X和y | |
| isTRUE(x) | 测试x是否为TRUE |
日期格式
| 符号 | 用途 | 示例 |
|---|---|---|
| %d | 数字表示的日期(0~31) | 01~31 |
| %a | 缩写的星期名 | Mon |
| %A | 非缩写星期名 | Monday |
| %m | 月份(00~12) | 00~12 |
| %b | 缩写的月份 | Jan |
| %B | 非缩写月份 | January |
| %y | 两位数的年份 | 07 |
| %Y | 四位数的年份 | 2007 |
| 判断 | 转换 |
|---|---|
| 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() |
常用的数学函数和简短的用例
| 函数 | 说明 |
|---|---|
| abs(x) | 绝对值,abs(-4)返回值为4 |
| sqrt(x) | 平方根sqrt(25)返回值为5,和25^(0.5)等价 |
| ceiling(x) | 不小于x的最小整数,ceiling(3.475)返回值为4 |
| floor(x) | 不大于x的最大整数,floor(3.475)返回值为3 |
| trunc(x) | 向 0 的方向截取的x中的整数部分,trunc(5.99)返回值为5 |
| round(x, digits=n) | 将x舍入为指定位的小数,round(3.475, digits=2)返回值为3.48 |
| signif(x, digits=n) | 将x舍入为指定的有效数字位数,signif(3.475, digits=2)返回值为3.5 |
| cos(x)、sin(x) 、tan(x) | 余弦、正弦和正切,cos(2)返回值为–0.416 |
| acos(x) 、asin(x) 、atan(x) | 反余弦、反正弦和反正切,acos(-0.416)返回值为2 |
| cosh(x) 、sinh(x) 、tanh(x) | 双曲余弦、双曲正弦和双曲正切,sinh(2)返回值为3.627 |
| acosh(x) 、asinh(x) 、atanh(x) | 反双曲余弦、反双曲正弦和反双曲正切,asinh(3.627)返回值为2 |
| log(x,base=n) log(x) log10(x) | 对x取以n为底的对数 为了方便起见,log(x)为自然对数 log10(x)为常用对数 log(10)返回值为2.3026 log10(10)返回值为1 |
| exp(x) | 指数函数,exp(2.3026)返回值为10 |
常用统计函数和简短用例
| 函数 | 说明 |
|---|---|
| mean(x) | 平均数,mean(c(1,2,3,4))返回值为2.5 |
| median(x) | 中位数,median(c(1,2,3,4))返回值为2.5 |
| sd(x) | 标准差,sd(c(1,2,3,4))返回值为1.29 |
| var(x) | 方差,var(c(1,2,3,4))返回值为1.67 |
| mad(x) | 绝对中位差(median absolute deviation),mad(c(1,2,3,4))返回值为1.48 |
| quantile(x,probs) | 求分位数。其中x为待求分位数的数值型向量,probs为一个由[0,1]之间的概率值组成 的数值向量 ,# 求x的30%和84%分位点,y <- quantile(x, c(.3,.84)) |
| range(x) | 求值域,x <- c(1,2,3,4),range(x)返回值为c(1,4) ,diff(range(x))返回值为3 |
| sum(x) | 求和,sum(c(1,2,3,4))返回值为10 |
| diff(x, lag=n) | 滞后差分,lag用以指定滞后几项。默认的lag值为1,x<- c(1, 5, 23, 29),diff(x)返回值为c(4, 18, 6) |
| min(x) | 求最小值,min(c(1,2,3,4))返回值为1 |
| max(x) | 求最大值,max(c(1,2,3,4))返回值为4 |
| scale(x,center=TRUE, scale=TRUE) | 为数据对象x按列进行中心化(center=TRUE)或标准化(center=TRUE,scale=TRUE); |
常用的概率函数列表
d = 密度函数(density)
p = 分布函数(distributionfunction)
q = 分位数函数(quantilefunction)
r = 生成随机数(随机偏差)
注:一般由上面四个字母与下面的分布组成函数,如rnorm(n)就是随机生成n个正态分布的数值。
以正态分布函数来举例说明一下这四个字母的组成及应用:
- 计算区间x=[-3,3]上概率密度函数值y:
y <- dnorm(pretty(c(-3, 3), 30), mean = 0, sd = 1)- 标准正态分布在z=1.96左侧区域所对应的累积概率:
p <- pnorm(1.96)- 均值μ=500、标准差σ=100的正态分布下第90百分位数:
q <- qnorm( prob = 0.9, mean = 500, sd = 10 )- 按照均值μ=50、标准差σ=12生成n=54个随机样本:
r <- rnorm(n = 54, mean = 58, sd = σ)
| 分布名称 | 缩 写 | 分布名称 | 缩 写 |
|---|---|---|---|
| Beta分布 | beta | Logistic分布 | logis |
| 二项分布 | binom | 多项分布 | multinom |
| 柯西分布 | cauchy | 负二项分布 | nbinom |
| (非中心)卡方分布 | chisq | 正态分布 | norm |
| 指数分布 | exp | 泊松分布 | pois |
| F分布 | f | Wilcoxon符号秩分布 | signrank |
| Gamma分布 | gamma | t分布 | t |
| 几何分布 | geom | 均匀分布 | unif |
| 超几何分布 | hyper | Weibull分布 | weibull |
| 对数正态分布 | lnorm | Wilcoxon秩和分布 | wilcox |
字符处理函数
| 函数 | 说明及用例 |
|---|---|
| nchar(x) | 计算x中的字符数量,x <- c(“ab”, “cde”, “fghij”),length(x)返回值为 3 ,nchar(x[3])返回值为5 |
| substr(x, start, stop) | 提取或替换一个字符向量中的子串,x <- “abcdef”,substr(x, 2, 4)返回值为”bcd”,substr(x, 2, 4) <- “12345”(x将变成”a123ef”,即将前三个字符替换过去) |
| grep(pattern, x, ignore.case=FALSE, fixed=FALSE) | 在x中搜索某种模式。若fixed=FALSE,则pattern为一个正 则表达式。若fixed=TRUE,则pattern为一个文本字符串。返回值为匹配的下标.grep(“A”,c(“b”,”A”,”c”),fixed=TRUE)返回值为2 |
| sub(pattern, replacement, x, ignore.case=FALSE, fixed=FALSE) | 在x中搜索pattern,并以文本replacement将其替换。若 fixed=FALSE, 则pattern为一个正则表达式。 若fixed=TRUE, 则pattern为一个文本字符串。sub(“\ s”,”.”,”Hello There”)返回值为Hello.There。 注意,”\s”是一个用来查找空白的正则表达式;使用”\ s”而 不用”\”的原因是,后者是R中的转义字符(使用?Quotes来了解更多) |
| strsplit(x, split, fixed=FALSE) | 在split处分割字符向量x中的元素。若fixed=FALSE,则pattern为一个正则表达式。若fixed=TRUE,则pattern为 一个文本字符串,y <- strsplit(“abc”, “”)将返回一个含有1个成分、3个 元素的列表,包含的内容为”a” “b” “c” unlist(y)[2]和sapply(y, “[“, 2)均会返回”b” |
| paste(…, sep=”“) | 连接字符串,分隔符为sep,paste(“x”, 1:3,sep=”“)返回值为c(“x1”, “x2”, “x3”),paste(“x”,1:3,sep=”M”)返回值为c(“xM1”,”xM2” “xM3”) paste(“Today is”, date())返回值为Today is Thu Jun 25 14:17:32 2011 |
| toupper(x) | 大写转换,toupper(“abc”)返回值为”ABC” |
| tolower(x) | 小写转换,tolower(“ABC”)返回值为”abc” |
其他实用函数
| 函数 | 说明及用例 |
|---|---|
| length(x) | 对象x的长度,x <- c(2, 5, 6, 9),length(x)返回值为4 |
| seq(from, to, by) | 生成一个序列,indices <- seq(1,10,2) indices的值为c(1, 3, 5, 7, 9) |
| rep(x, n) | 将x重复n次,y <- rep(1:3, 2),y的值为c(1, 2, 3, 1, 2, 3) |
| cut(x, n) | 将连续型变量x分割为有着n个水平的因子 使用选项ordered_result = TRUE以创建一个有序型因子 |
| pretty(x, n) | 创建美观的分割点。通过选取n+1个等间距的取整值,将一个连续型变量x分割为n个 区间。绘图中常用 |
| cat(.. , file =”myfile”, append =FALSE) | 连接…中的对象,并将其输出到屏幕上或文件中(如果声明了一个的话)firstname <- c(“Jane”) |
