R语言学习笔记与感悟一
学习内容:1.理解数据分析系统2.R与RStudio的关系、RStudio的基本使用3.注意事项、帮助函数、管理工作空间的函数、文本与图形的输入与输出4.数据结构、数据的输入5.添加变量标签和值标签、处理数据对象的函数
主要学习材料:1.《R语言实战》Chapter 1&22.猴子知乎Live第二讲:
数据结构入门 盖房子 = 材料 + 整合材料程序 = 数据结构 + 算法
R与RStudio的区别:
R是运行环境;RStudio是开发工具,为了更方便地使用R语言,用于代码的编辑、调试、图形显示。
在RStudio中导入数据后,工作空间中会显示内存中保存的对象。
R Studio中的注释部分与代码部分有颜色的区分,内置函数与外来输入的部分能通过颜色区分。
RStudio的使用:
1. RStudio的组成:
控制台Console:输入命令及显示输出结果
代码编辑器
工作空间
目录,同时也是图形输出设备所在处
2. 创建项目和脚本
File -> New Project -> New Directory -> Empty Project
File -> New File -> R Script在脚本中写入R的代码,脚本文件的后缀为.R
3. 运行代码
Step1: 在脚本中选中要运行的代码Step2: Code — Run Lines运行结果会显示在控制台中
4. 更改RStudio背景色
Tools -> Global Options -> Appearance然后在Editor Theme中选择背景
5. R Studio中的快捷键
第一章 R语言介绍
一、注意事项:
区分大小写 逻辑值TRUE和FALSE全部大写
在命令提示符(>)后每次输入并执行一条命令,或者一次性执行写在脚本文件中的一组命R使用<-,而不是传统的 = 作为赋值符
注释由符号 # 开头,在 # 之后出现的任何文本都会被R解释器忽略
路径中使用一个正斜杠/或两个反斜杠\\,使用引号闭合目录名和文件名
输入字符串时要加引号,单引号和双引号皆可
二、常用函数:
(截图来自《R语言实战》)
注意:
导入数据前,必须先设置当前工作目录要导入存在另一个工作目录下的数据,必须先改变工作目录再读入数据
函数setwd()不会自动创建一个不存在的目录。可以使用函数dir.create()来创建新目录,然后使用setwd()将工作目录指向这个新目录。
启动一个R会话时使用setwd()命令指定到某一个项目的路径,后接不加选项的load()命令,这样做可以从上一次会话结束的地方重新开始。
实践示例:setwd("C:/myprojects/project1") #当前工作目录被设置为C:/myprojects/project1 options() #当前的选项设置情况将显示出来 options(digits=3) #显示为小数点后三位有效数字 x <- runif(20) #创建一个包含20个均匀分布随机变量的向量 summary(x) #生成摘要统计量 hist(x) #生成直方图 savehistory() #命令的历史记录保存到文件.Rhistory中 save.image() #工作空间(包含向量x)保存到文件.RData中 q() #会话结束
三、输入与输出
输入:
函数source("filename")可在当前会话中执行一个脚本。如果文件名中不包含路径,R将假设此脚本在当前工作目录中。
文本输出:
函数sink("filename")将输出重定向到文件filename中。使用参数append=TRUE可以将文本追加到文件后,而不是覆盖它。参数split=TRUE可将输出同时发送到屏幕和输出文件中。不加参数调用命令sink()将仅向屏幕返回输出结果。
图形输出:
要重定向图形输出,使用表1-4中列出的函数即可。最后使用dev.off()将输出返回到终端。
实践示例1:
sink("myoutput", append=TRUE, split=TRUE)
pdf("mygraphs.pdf")
source("script2.R")
文件script2.R中的R代码将执行,结果也将显示在屏幕上。此外,文本输出将被追加到文件myoutput中,图形输出将保存到文件mygraphs.pdf中。
实践示例2:
sink()
dev.off()
source("script3.R")
文件script3.R中的R代码将执行,结果将显示在屏幕上,没有文本和图形输出保存到文件中。
待解决疑问1:
在上述两个示例中,为什么不是先使用输入函数source(),而是先使用输出函数?
四、R包
install.packages("package_name")安装包
library("package_name")载入包,包安装后必须先载入才能使用
update.packages("package_name")更新已经安装的包
search()可以告诉你哪些包已加载并可使用
installed.packages()查看已安装的包的描述,将列出安装的包
library()显示库(存储包的目录)中有哪些包
.libPaths()显示库所在的位置
help(package="package_name")可以输出某个包的简短描述以及包中的函数名称和数据集名称的列表
实践示例:
install.packages("vcd") #安装vcd包
help(package="vcd") #列出此包中可用的函数和数据集
library(vcd) #载入这个包
help(Arthritis) #查看数据集Arthritis的描述
Arthritis #显示数据集Arthritis的内容
example(Arthritis) #运行数据集Arthritis的自带的示例
q() #退出
第二章 创建数据集(数据分析的第一步)
包括两个步骤:1.选择一种数据结构来存储数据;2.将数据输入或导入到这个数据结构中。
一、数据结构
向量、矩阵、数组中的数据必须是同种类型;数据框和列表中的数据可以是不同类型
1. 向量
向量是用于存储数值型、字符型或逻辑型数据的一维数组。用函数c()来创建向量。
a <- c(1,2,5,3,6,-2,4)
b <- c("one", "two", "three")
c <- c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE)
使用:
单个向量中的数据必须拥有相同的数据类型(数值型、字符型或逻辑型)。
获取向量的长度 length(vector_name)
要访问向量中的某个元素,在方括号中给定元素所处位置的数值,例如:a[c(2, 4)]用于访问向量a中的第二个和第四个元素。
由于R中内置了同名函数c(),最好不要在编码时使用c作为对象名。
R中没有标量。标量是只含一个元素的向量,例如f <- 3、g <- "US"和h <- TRUE ,它们用于保存常量。
冒号用于生成一个数值序列。例如,a <- c(2:6)等价于a <- c(2,3, 4, 5, 6)。
2. 矩阵
矩阵是一个二维数组,每个元素都拥有相同的类型(数值型、字符型或逻辑型)。
可通过函数matrix创建矩阵。
mymatrix <- matrix(vector,
nrow=number_of_rows, ncol=number_of_columns,
byrow=logical_value,
dimnames=list(char_vector_rownames, char_vector_colnames))
vector包含了矩阵的元素,是一个向量
nrow和ncol用以指定行和列的维数
byrow则表明矩阵应当按行填充(byrow=TRUE)还是按列填充(byrow=FALSE),默认情况下按列填充
dimnames包含了可选的、以字符型向量表示的行名和列名实践示例:cells <- c(1,26,24,68) rnames <- c("R1", "R2") cnames <- c("C1", "C2") mymatrix <- matrix(cells, nrow=2, ncol=2, byrow=TRUE, dimnames=list(rnames, cnames)使用:
访问矩阵中的行、列或元素X[i,]指矩阵X中的第i 行,X[,j]指第j 列,X[i, j]指第i 行第j 个元素,如:x[2,] #选取矩阵x中第二行的元素x[,2] #选取矩阵x中第二列的元素x[1,4] #选取矩阵x中位于第一行第四列的元素选择多行或多列时,下标i 和j 可为数值型向量,如:x[1, c(4,5)] #选取矩阵x第一行中位于第四列和第五列的元素
矩阵的作用: 绘制图形
3. 数组
数组(array)维度可以大于2,数据只能拥有一种类型。行表示观测,列表示变量。
数组可通过array函数创建。myarray <- array(vector, dimensions, dimnames)
vector包含了数组中的数据 ,是一个向量
dimensions是数值型向量,给出了各个维度下标的最大值
dimnames是各维度名称的列表实践示例:data <- 1:24 dim1 <- c("A1", "A2") dim2 <- c("B1", "B2", "B3") dim3 <- c("C1", "C2", "C3", "C4") z <- array(data, c(2, 3, 4), dimnames=list(dim1, dim2, dim3))
4.数据框
数据框是数据分析中最常用的数据结构不同的列可以包含不同类型(数值型、字符型等)的数据,但是每一列的数据类型必须唯一。
数据框可通过函数data.frame()创建。mydata <- data.frame(col1, col2, col3, ...)
使用:
选取数据框中元素1.使用下标记号patientdata[1:2] #选取名为patientdata数据框中的第一列至第二列元素2.直接指定列名patientdata[c("diabetes", "status")] #选取patientdata数据框中列名分别为diabetes和status所在列的元素3.用$和列名选取一个给定数据框中的某一列patientdata$age #选取patientdata数据框中列名为age所在列的元素
求数据框的行数例如:求患者总数patientNumber <- nrow(patientdata)
求满足某一特征的数据个数例如:求患有“1型糖尿病”的患者人数Step1: 使用==找到符合条件的数据,并赋值给新的数据框type1 <- patientdata[patientdata$diabetes == "1型糖尿病"]type1也是一个数据框,仅包含符合糖尿病类型为“1型糖尿病”的患者Step2: 求type1数据框的行数type1.number <- nrow(type1)对象名称中的句点(.)没有特殊意义。
在数据框中按行添加新数据用rbind函数Step1:将要添加的数据放入新的数据框中
patientID <- c(5)
age <- c(30)
diabetes <- c("1型糖尿病")
status <- c("较差")
newPatient <- data.frame(patientID, age, diabetes, status, stringsAsFactors=FALSE)
Step2:将新数据框用rbind函数加入原数据框patientdata <- rbind(patientdata, newPatient)
在数据框中按列添加新数据用cbind函数Step1:由于列在数据框中相当于向量,所以将新数据首先放入新的向量中inTime <- c("2015-3-1", "2014-12-31", "2015-10-1", "2015-5-1", "2016-12-31")Step2:将新定义的向量用cbind函数加入原数据框patientdata <- cbind(patientdata, inTime)
5.列表
列表允许将若干(可能无关的)对象整合到单个对象名下。例如,某个列表中可能是若干向量、矩阵、数据框,甚至其他列表的组合。
使用函数list()创建列表mylist <- list(object1, object2, ...)还可以为列表中的对象命名mylist <- list(name1=object1, name2=object2, ...)其中的对象可以是目前为止讲到的任何结构。
使用:
常用于存储各种类型函数的返回结果
计算业务指标KPI例如:存储业务指标一“患有‘1型糖尿病’的患者信息”和业务指标二“病人的数量”为KPI结果kpi <- list(diabetesType=type1, number=number) #列表中的业务指标一diabetesType是一个数据框,业务指标二number是一个数值,起名字是为了方便后期查找
访问列表中的元素在双重方括号中指明代表某个成分的数字或名称例如:获取列表中的业务指标二“病人数量”,并赋值给向量numbernumber <- kpi[["number"]]或number <- kpi[[2]] #获取列表kpi中的第二个成分,并赋值给numbe
6.因子
变量可归结为名义型、有序型或连续型变量。
名义型变量是没有顺序之分的类别变量。糖尿病类型Diabetes(Type1、Type2)是名义型变量,即使在数据中Type1编码为1而Type2编码为2,也不意味着二者是有序的。
有序型变量表示一种顺序关系,而非数量关系。病情Status(poor, improved, excellent)是顺序型变量,病情为poor(较差)病人的状态不如improved(病情好转)的病人,但并不知道相差多少。
连续型变量可以呈现为某个范围内的任意值,并同时表示了顺序和数量。年龄Age就是一个连续型变量,它能够表示像14.5或22.8这样的值以及其间的其他任意值。15岁的人比14岁的人年长一岁
因子:类别(名义型)变量和有序类别(有序型)变量在R中称为因子(factor)。因子在R中非常重要,因为它决定了数据的分析方式以及如何进行视觉呈现。
函数factor()以一个整数向量的形式存储类别值,整数的取值范围是[1... k ](其中k 是名义型变量中唯一值的个数),同时一个由字符串(原始值)组成的内部向量将映射到这些整数上。举例来说,假设有向量:diabetes <- c("Type1", "Type2", "Type1", "Type1")语句diabetes <- factor(diabetes)将此向量存储为(1, 2, 1, 1),并在内部将其关联为1=Type1和2=Type2(具体赋值根据字母顺序而定)。针对向量diabetes进行的任何分析都会将其作为名义型变量对待,并自动选择适合这一测量尺度的统计方法。(这里的测量尺度是指定类尺度、定序尺度、定距尺度、定比尺度中的定类尺度。)
要表示有序型变量,需要为函数factor()指定参数ordered=TRUE给定向量:status <- c("Poor", "Improved", "Excellent", "Poor")语句status <- factor(status, ordered=TRUE)会将向量编码为(3, 2, 1, 3),并在内部将这些值关联为1=Excellent、2=Improved以及3=Poor。针对此向量进行的任何分析都会将其作为有序型变量对待,并自动选择合适的统计方法。对于字符型向量,因子的水平默认依字母顺序创建。可以通过指定levels选项来覆盖默认排序。例如:
status <- factor(status, ordered=TRUE,
levels=c("Poor", "Improved", "Excellent"))
各水平的赋值将为1=Poor、2=Improved、3=Excellent。
关于$使用的补充:当需要多次重复引用同一个数据框名称时,为了避免在每个变量名前都键入一次“数据框名称+$”,可以通过以下替代方法:
使用attach()和detach()函数attach()可将数据框添加到R的搜索路径中。函数detach()将数据框从搜索路径中移除。R在遇到一个变量名以后,将检查搜索路径中的数据框,以定位到这个变量。例如:从mtcars数据框中获取每加仑行驶英里数(mpg)变量的描述性统计量,并分别绘制此变量与发动机排量(disp)和车身重量(wt)的散点图:
attach(mtcars)
summary(mpg)
plot(mpg, disp)
plot(mpg, wt)
detach(mtcars)
此方法主要适用于名称相同的对象只有一个的情况。若数据框被绑定之前已经用与数据框中某对象相同的名称定义了新的对象,则该新对象取得优先权,可能会由于两个对象的元素个数不同而出错。
使用with()函数对于上例:
with(mtcars, {
summary(mpg, disp, wt)
plot(mpg, disp)
plot(mpg, wt)
})
大括号{}之间的语句都针对数据框mtcars执行,这样就无须担心名称冲突了。如果仅有一条语句(例如summary(mpg)),那么大括号{}可以省略。函数with()的局限性: 赋值仅在此函数的括号内生效。要创建在with()结构以外存在的对象,使用特殊赋值符<<-替代标准赋值符(<-)。
实例标识符在R中,实例标识符(case identifier)可通过数据框操作函数中的rowname选项指定。例如,在病例数据中,病人编号(patientID)用于区分数据集中不同的个体:
patientdata <- data.frame(patientID, age, diabetes, status,
row.names=patientID)
二、数据的输入(最常用的几种)
1. 使用键盘输入数据
对于小数据集很有效函数edit()会自动调用一个允许手动输入数据的文本编辑器。
Step1: 创建一个空数据框(或矩阵),其中变量名和变量的模式需与理想中的最终数据集一致;
Step2: 针对这个数据对象调用文本编辑器,输入数据,并将结果保存回此数据对象中。
例如:创建一个名为mydata的数据框,含有三个变量:age(数值型)、gender(字符型)和weight(数值型),然后调用文本编辑器,键入数据,最后保存结果。
mydata <- data.frame(age=numeric(0), gender=character(0), weight=numeric(0))
mydata <- edit(mydata)
类似于age=numeric(0)的赋值语句将创建一个指定数据类型但不含实际数据的变量。
编辑的结果需要赋值回对象本身!!!!!!语句mydata <- edit(mydata)的一种简捷的等价写法是fix(mydata)。
调用出文本编辑器后,单击列的标题,可以用编辑器修改变量名和变量类型(数值型、字符型)。还可以通过单击未使用列的标题来添加新的变量。
2. 从带分隔符的文本文件导入数据
使用read.table()函数,可读入一个表格格式的文件并将其保存为一个数据框。mydataframe <- read.table(file, header=logical_value, sep="delimiter", row.names="name"
file是一个带分隔符的ASCII文本文件
header是一个表明首行是否包含了变量名的逻辑值(TRUE或FALSE)
sep用来指定分隔数据的分隔符
row.names是一个可选参数,用以指定一个或多个表示行标识符的变量
例如:从当前工作目录中读入了一个名为studentgrades.csv的逗号分隔文件,从文件的第一行取得了各变量名称,将变量STUDENTID指定为行标识符,最后将结果保存到了名为grades的数据框中。grades <- read.table("studentgrades.csv", header=TRUE, sep=",", row.names="STUDENTID")
默认情况下,字符型变量将转换为因子。禁止这种转换的方法:
法一:设置stringsAsFactors=FALSE
法二:使用选项colClasses为每一列指定一个类,例如logical(逻辑型)、numeric(数值型)、character(字符型)、factor(因子)。
3. 导入Excel数据
读取一个Excel文件的最好方式,就是在Excel中将其导出为一个逗号分隔文件(csv),并使用前文描述的方式将其导入R中。
在Windows系统中,也可以使用RODBC包来访问Excel文件。
实践示例:
install.packages("RODBC")
library(RODBC)
channel <- odbcConnectExcel("myfile.xls")
mydataframe <- sqlFetch(channel, "mysheet")
odbcClose(channel)
myfile.xls是一个Excel文件mysheet是要从这个工作簿中读取工作表的名称channel是一个由odbcConnectExcel()返回的RODBC连接对象mydataframe是返回的数据框
XLSX格式的电子表格,可以用xlsx包来读取。xlsx包不仅仅可以导入数据表,它还能够创建和操作XLSX文件。包中的函数read.xlsx()可将XLSX文件中的工作表导入为一个数据框。其最简单的调用格式是read.xlsx(file, n),其中file是Excel工作簿的所在路径,n则为要导入的工作表序号。
library(xlsx)
workbook <- "C:/myworkbook.xlsx"
mydataframe <- read.xlsx(workbook,1)
从位于C盘根目录的工作簿myworkbook.xlsx中导入了第一个工作表,并将其保存为一个数据框mydataframe。
4.从网页抓取数据
使用函数readLines()下载网页,然后使用如grep()和gsub()一类的函数处理它。对于结构复杂的网页,可以使用RCurl包和XML包来提取其中想要的信息。
其他还包括导入XML数据、导入SPSS数据、导入SAS数据、导入Stata数据、导入netCDF数据、导入HDF5 数据、访问数据库管理系统、通过Stat/Transfer导入数据,等用到时再详细补充,现在理解起来有些抽象。
三、数据集的标注
1. 变量标签
为变量名添加描述性的标签方法:将变量标签作为变量名,然后通过位置下标来访问这个变量。
例如,对于数据框patientdata中的第二列包含着个体首次入院时年龄的变量age,附加一个描述更详细的标签“Age at hospitalization (in years)”(入院年龄)names(patientdata)[2] <- "Age at hospitalization(in years)"将age重命名为"Age at hospitalization (in years)"。新的变量名太长,不适合重复输入,作为替代,可以使用patientdata[2]来引用这个变量,而在本应输出age的地方输出字符串"Age at hospitalization (in years)"。
待解决疑问2:为变量名添加描述性标签是否等同于更改变量名?
2. 值标签
函数factor()为类别型变量中的编码添加值标签
例如,假设有一个名为gender的变量,其中1表示男性,2表示女性,将其关联到标签“male”和“female”上
patientdata$gender <- factor(patientdata$gender,
levels=c(1,2),
labels=c("male", "female"))
注意:这里levels标签中的数字代表实际值而不是顺序!
四、处理数据对象的实用函数
学习感悟:
正在努力培养自己将知识形成体系的能力,刚刚选定OneNote作为主要工具,各种功能还在进一步的探索当中。R语言的这部分内容在第一遍学习时,就边学边进行了整理,算是把书读薄的过程,这次是第二遍,在脑中形成了知识架构,同时把零散的知识点插入到架构中合适的位置。知识结构清晰后,很多原有的疑惑会迎刃而解,同时也会发现新的问题,接下来还会不断在实践中巩固容易遗忘的知识点并解决老问题。
最近一直在摸索适合自己的学习方式。我在吸收新知识方面比较慢,所以第一遍都会踏踏实实地学习,标记出不明白的地方,但是不会硬磕,过一段时间再看看可能就自然而然地想通了,很多时候后续知识的学习会促进前期知识的理解。因为记忆力一般,所以学习新知识时更适合拿出整块的时间来学习同一科目,这样可以有效降低每次学习前都要先回顾之前的知识点而花费的时间。
数据分析咨询请扫描二维码
在准备数据分析师面试时,掌握高频考题及其解答是应对面试的关键。为了帮助大家轻松上岸,以下是10个高频考题及其详细解析,外加 ...
2024-12-20互联网数据分析师是一个热门且综合性的职业,他们通过数据挖掘和分析,为企业的业务决策和运营优化提供强有力的支持。尤其在如今 ...
2024-12-20在现代商业环境中,数据分析师是不可或缺的角色。他们的工作不仅仅是对数据进行深入分析,更是协助企业从复杂的数据信息中提炼出 ...
2024-12-20随着大数据时代的到来,数据驱动的决策方式开始受到越来越多企业的青睐。近年来,数据分析在人力资源管理中正在扮演着至关重要的 ...
2024-12-20在数据分析的世界里,表面上的技术操作只是“入门票”,而真正的高手则需要打破一些“看不见的墙”。这些“隐形天花板”限制了数 ...
2024-12-19在数据分析领域,尽管行业前景广阔、岗位需求旺盛,但实际的工作难度却远超很多人的想象。很多新手初入数据分析岗位时,常常被各 ...
2024-12-19入门数据分析,许多人都会感到“难”,但这“难”究竟难在哪儿?对于新手而言,往往不是技术不行,而是思维方式、业务理解和实践 ...
2024-12-19在如今的行业动荡背景下,数据分析师的职业前景虽然面临一些挑战,但也充满了许多新的机会。随着技术的不断发展和多领域需求的提 ...
2024-12-19在信息爆炸的时代,数据分析师如同探险家,在浩瀚的数据海洋中寻觅有价值的宝藏。这不仅需要技术上的过硬实力,还需要一种艺术家 ...
2024-12-19在当今信息化社会,大数据已成为各行各业不可或缺的宝贵资源。大数据专业应运而生,旨在培养具备扎实理论基础和实践能力,能够应 ...
2024-12-19阿里P8、P9失业都找不到工作?是我们孤陋寡闻还是世界真的已经“癫”成这样了? 案例一:本硕都是 985,所学的专业也是当红专业 ...
2024-12-19CDA持证人Louis CDA持证人基本情况 我大学是在一个二线城市的一所普通二本院校读的,专业是旅游管理,非计算机非统计学。毕业之 ...
2024-12-18最近,知乎上有个很火的话题:“一个人为何会陷入社会底层”? 有人说,这个世界上只有一个分水岭,就是“羊水”;还有人说,一 ...
2024-12-18在这个数据驱动的时代,数据分析师的技能需求快速增长。掌握适当的编程语言不仅能增强分析能力,还能帮助分析师从海量数据中提取 ...
2024-12-17在当今信息爆炸的时代,数据分析已经成为许多行业中不可或缺的一部分。想要在这个领域脱颖而出,除了热情和毅力外,你还需要掌握 ...
2024-12-17数据分析,是一项通过科学方法处理数据以获取洞察并支持决策的艺术。无论是在商业环境中提升业绩,还是在科研领域推动创新,数据 ...
2024-12-17在数据分析领域,图表是我们表达数据故事的重要工具。它们不仅让数据变得更加直观,也帮助我们更好地理解数据中的趋势和模式。相 ...
2024-12-16在当今社会,我们身处着一个飞速发展、变化迅猛的时代。不同行业在科技进步、市场需求和政策支持的推动下蓬勃发展,呈现出令人瞩 ...
2024-12-16在现代商业世界中,数据分析师扮演着至关重要的角色。他们通过解析海量数据,为企业战略决策提供有力支持。要有效完成这项任务, ...
2024-12-16在当今数据爆炸的时代,数据分析师是组织中不可或缺的导航者。他们通过从大量数据中提取可操作的洞察力,帮助企业在竞争激烈的市 ...
2024-12-16