本次实验共100分钟,零基础可入门,完成后你将完整了解:
现在铺的路,都是老师当年踩过的坑啊
- 用RStudio,尽量不使用原生RGui
RStudio 是 R 的标准集成开发环境,一站式完成写代码、看数据、出图、查报错、管理文件,是学术界、企业界唯一主流工具。
- 所有代码写在.R脚本中,绝不直接写控制台
控制台代码无法保存、无法回溯、无法复用。脚本可以分段运行、随时修改、永久留存,是作业、实验、数据分析的标准方式。
- 写地道R向量化代码,拒绝C/Java循环风格
R是向量化语言,优先向量运算、列运算、批量运算。尽量少写for循环、多层if嵌套,代码更短、速度更快、更贴合R原生逻辑。(当然,你后面熟悉了,也会有不得已使用循环的时候。但在R里,尽量少用循环,除非不得已。)
- 善用R扩展包生态,不重复造轮子
R的核心优势是开源包生态,统计、绘图、清洗、建模全部有成熟工具。熟练掌握
install.packages()安装包、library()加载包。
- 代码必写注释,变量命名规范整洁
所有关键代码必须用
#添加注释,注释解释目的而非解释过程;变量使用下划线命名法,整洁易懂。
- 先探查数据,再分析建模
导入数据后,固定执行三步探查:
head()、str()、summary()。新手90%报错,都是“不看数据直接写代码”导致。
- 分清大小写,全程使用英文半角符号
R语言对大写小写敏感,
XinYu和xinyu,在R中是两个对象。中文逗号、中文括号、中文引号会100%报错。所有代码符号必须是半角英文。
- 善用官方帮助文档,拒绝死记硬背
不确定函数直接运行
?函数名,官方文档包含解释、参数、案例,是最高效的学习工具。
- 保护原始数据,绝不原地修改源文件
原始CSV、Excel、TXT文件永久只读不修改。所有数据清洗、衍生变量、筛选操作全部新建对象保存,防止数据不可逆损坏。
- 读懂报错信息,不畏惧红色提示
R报错精准定位问题:对象不存在、类型不匹配、长度不一致、参数缺失。读懂报错是进步最快的方式。
- 使用RStudio Project管理所有项目
建立
.Rproj项目文件,自动绑定工作目录,文件结构整洁、换电脑不报错。(我们涉及到项目的时候再说)
打开RStudio默认四分区界面:
在正式新建脚本写代码之前,我们先学会 R
项目管理。数据分析、科研、作业、课程练习,不要裸跑代码!(从开始就养成好习惯)所有课程练习、所有作业、所有数据分析,全部统一放在一个
.Rproj 项目中。
RStudio 项目(Project)是一个独立、干净、自带工作目录的工作文件夹。
一个项目 = 一个课题 = 一个文件夹 = 一套独立代码环境
我们把整门R语言课程当成一个完整数据分析项目:
项目名称:R_Learning_你的昵称(其实你喜欢起什么项目名都行)
项目内部固定结构(构建完项目以后打开目录看看)
code/ 存放每节课的所有 .R 脚本data/
存放原始数据(csv、excel、txt,永远不修改)output/ 存放导出结果、图片、表格R_Learning_Project.Rproj 项目主文件R_Learning_你的昵称成功后:
.Rproj 项目文件用写 setwd() 手动设置路径 入数据直接写
read.csv("data/xxx.csv") 换电脑、交作业、打包发送
零路径报错 代码、数据、结果完全分离,符合科研规范
每节课新增脚本,全部放进 code 文件夹,永不混乱
当开始用Rstudio的项目管理时,你已经看起来很专业啦!
File -> New File -> R ScriptCtrl+Shift+NCtrl+S.R,建议英文命名、无中文、无空格。Ctrl+Enter或者runSource# 我的第一段标准R代码
print("Hello RStudio!上帝无谓男女,编程不分文理!")
## [1] "Hello RStudio!上帝无谓男女,编程不分文理!"
# 我的第一副图
x<-seq(-4,4,0.1)
y<-dnorm(x)
plot(x,y,xlab="随机变量值",ylab="概率密度",main="传说中的标准正态分布",col="red",typ="l",lwd=3)
R中所有数据都有对应的类型,只有理解数据类型,才会明白为什么有些运算会报错。基础四大类型是后续向量、数据框的底层基石。
R标准赋值符号:<-(快捷键
Alt+-),= 不要混用赋值风格,全程统一
<-
a <- 100
b <- 30
# 基础算术运算
a + b
## [1] 130
a - b
## [1] 70
a * b
## [1] 3000
a / b
## [1] 3.333333
a ^ 2 # 平方
## [1] 10000
a %% b # 取余
## [1] 10
a %/% b # 整除
## [1] 3
R原生核心数据类型,所有数据都基于以下四类:
| 类型 | 作用 | 示例 |
|---|---|---|
| 数值型 numeric | 小数、整数、连续数据 | 3.14 60 |
| 字符型 character | 文本、标签、分类文本 | "男" "张三" |
| 逻辑型 logical | 判断真假,仅两值 | TRUE FALSE |
| 缺失值 NA | 空数据、未观测数据 | NA |
# 四类数据类型演示
num_var <- 66.5
char_var <- "R语言学习"
log_var <- TRUE
na_var <- NA
# 查看数据类型
class(num_var)
## [1] "numeric"
class(char_var)
## [1] "character"
class(log_var)
## [1] "logical"
NA代表缺失观测,任何运算只要包含NA,默认结果就会是NA。在统计分析的时候,我们常常需要手动设置参数忽略缺失值才能正常计算。
score <- c(88,76,NA,92,65)
mean(score) # 默认含NA,结果NA
## [1] NA
mean(score, na.rm=TRUE) # 忽略缺失值计算
## [1] 80.25
向量是R中最基础的数据容器,R的设计理念就是面向向量批量运算,这也是R和C、Python最大区别之一。向量里面所有元素必须是同一个数据类型。
向量是R的最小运算单元,所有批量运算基于向量
# c() 拼接创建向量
income <- c(3200,5600,4800,7100,2900)
R的索引从1开始,不是0!可以通过方括号提取向量中部分元素;还可以用逻辑条件筛选元素。
income[1] # 取第1个
## [1] 3200
income[2:4] # 连续取值
## [1] 5600 4800 7100
income[-1] # 删除第1个
## [1] 5600 4800 7100 2900
income[income>4000]# 逻辑筛选
## [1] 5600 4800 7100
#如何把score这个向量的NA值,替换成100呢?
不需要写循环,直接对整个向量做运算,R会自动对每一个元素批量计算,简洁高效。
income + 500
## [1] 3700 6100 5300 7600 3400
income * 1.2
## [1] 3840 6720 5760 8520 3480
income / 1000
## [1] 3.2 5.6 4.8 7.1 2.9
length(income)
## [1] 5
sum(income)
## [1] 23600
mean(income)
## [1] 4720
max(income)
## [1] 7100
min(income)
## [1] 2900
sort(income)
## [1] 2900 3200 4800 5600 7100
在模拟实验、抽样、生成自变量时,我们经常需要生成有序序列或者随机数。
# 1.简单连续序列
1:15
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 2.自定义步长序列
seq(from=2, to=30, by=4)
## [1] 2 6 10 14 18 22 26 30
# 3.固定数量等分序列
seq(1,10,length.out=6)
## [1] 1.0 2.8 4.6 6.4 8.2 10.0
# 4.重复序列
rep(c(1,2,3), times=2)
## [1] 1 2 3 1 2 3
rep(c("A","B"), each=3)
## [1] "A" "A" "A" "B" "B" "B"
计算机生成的是伪随机数。设置set.seed(),可以固定随机结果,保证你的实验代码别人运行,得到一模一样的结果,满足科研可复现要求。
set.seed(123) # 固定随机种子
rnorm(n=8, mean=50, sd=10) # 正态随机数
## [1] 44.39524 47.69823 65.58708 50.70508 51.29288 67.15065 54.60916 37.34939
runif(n=8, min=0, max=100) # 均匀随机数
## [1] 24.608773 4.205953 32.792072 95.450365 88.953932 69.280341 64.050681
## [8] 99.426978
dnorm(0)
## [1] 0.3989423
pnorm(1.96)
## [1] 0.9750021
qnorm(0.975)
## [1] 1.959964
rnorm(10)
## [1] 0.4007715 0.1106827 -0.5558411 1.7869131 0.4978505 -1.9666172
## [7] 0.7013559 -0.4727914 -1.0678237 -0.2179749
运算符用来做计算、比较、条件判断,是筛选数据、构建逻辑条件的基础。
+ - * / ^ %% %/% 用于数值计算
# 算术运算示例(同1.1 再练一下也好)
x <- 10
y <- 3
x + y # 加法
## [1] 13
x - y # 减法
## [1] 7
x * y # 乘法
## [1] 30
x / y # 除法
## [1] 3.333333
x ^ 2 # 平方
## [1] 100
x %% y # 取余数
## [1] 1
x %/% y # 整数除法
## [1] 3
> < >= <= == != 比较大小、判断相等,返回
TRUE / FALSE
# 关系运算示例
a <- c(12, 25, 30, 47)
a > 20
## [1] FALSE TRUE TRUE TRUE
a == 30
## [1] FALSE FALSE TRUE FALSE
a != 25
## [1] TRUE FALSE TRUE TRUE
a <= 40
## [1] TRUE TRUE TRUE FALSE
& | ! (向量多条件筛选,逐元素判断)
&& || (if条件判断,只看第一个元素)
# 逻辑运算示例
v <- c(15, 28, 33, 46)
v > 20 & v < 40 # 向量,同时满足两个条件
## [1] FALSE TRUE TRUE FALSE
v < 20 | v > 40 # 向量,满足任一条件
## [1] TRUE FALSE FALSE TRUE
!(v > 30) # ! 取反,不大于30
## [1] TRUE TRUE FALSE FALSE
# && 和 || 只判断一个元素
(v > 20)[1] && (v < 40)[1]
## [1] FALSE
vec <- c(20,35,41,55,68)
# 筛选大于30并且小于60的元素
vec[vec > 30 & vec < 60]
## [1] 35 41 55
向量是单类型一维结构;因子专门处理分类变量;数据框就是R里的表格(最常用);列表是最灵活的复合型容器。
因子(factor)专门用来存储分类数据,例如性别、组别、品种。R会记录类别水平,在回归、方差分析、绘图时会自动识别为分类变量,而不是普通文本。
gender <- c("男","女","男","女")
gender_fac <- factor(gender)
str(gender_fac)
## Factor w/ 2 levels "男","女": 1 2 1 2
数据框就是R中的数据表,类似Excel表格:每一列可以是不同类型,但每一列长度必须相同。社会科学、统计分析绝大多数原始数据都是数据框格式。
df <- data.frame(
name = c("张三","李四","王五"),
score = c(88,92,79),
pass = c(T,T,F)
)
df$score
## [1] 88 92 79
df[df$score>80,]
## name score pass
## 1 张三 88 TRUE
## 2 李四 92 TRUE
列表是R里最灵活的数据容器,可以把不同类型、不同长度的数据放在同一个对象里。向量要求所有元素类型一致;数据框要求每一列长度相同;但列表不受限制,可以同时存放数值向量、文本、数据框,甚至其他列表。
# 构建一个复合型列表:同时包含向量、数据框、单个字符串
mylist <- list(
num_vec = c(1, 2, 3),
student_df = df,
note = "这是一个复合型列表,可以存放多种不同类型数据"
)
# 查看整个列表
mylist
## $num_vec
## [1] 1 2 3
##
## $student_df
## name score pass
## 1 张三 88 TRUE
## 2 李四 92 TRUE
## 3 王五 79 FALSE
##
## $note
## [1] "这是一个复合型列表,可以存放多种不同类型数据"
# 提取列表第1个元素:数值向量
mylist[[1]]
## [1] 1 2 3
# 提取列表第2个元素:数据框
mylist[[2]]
## name score pass
## 1 张三 88 TRUE
## 2 李四 92 TRUE
## 3 王五 79 FALSE
# 按名字提取列表里的数据框
mylist$student_df
## name score pass
## 1 张三 88 TRUE
## 2 李四 92 TRUE
## 3 王五 79 FALSE
流程控制用来做条件判断、循环;自定义函数允许我们封装重复代码,提升代码复用性。记住R优先向量化,循环尽量少用。
ifelse() 是R推荐的向量化条件判断函数,一次性对向量全部元素判断,不要写循环逐个判断。
s <- c(55,66,88,45)
ifelse(s>=60,"及格","不及格")
## [1] "不及格" "及格" "及格" "不及格"
for循环可以遍历元素,但在R中速度慢,优先用向量运算替代。只需要看懂,日常尽量不写。
for(i in 1:3){
print(i)
}
## [1] 1
## [1] 2
## [1] 3
把重复使用的代码打包成函数,输入参数,返回结果,减少重复代码。
bmi_calc <- function(h,w){
return(w/(h/100)^2)
}
bmi_calc(175,70)
## [1] 22.85714
拿到数据集之后,第一步永远是探查数据;然后筛选、新增变量,最后可视化。这是一套标准数据分析工作流。
data(iris)
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
str(iris)
## 'data.frame': 150 obs. of 5 variables:
## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
summary(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
## 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
## Median :5.800 Median :3.000 Median :4.350 Median :1.300
## Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
## 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
## Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
## Species
## setosa :50
## versicolor:50
## virginica :50
##
##
##
数据集介绍:鸢尾花(iris)数据集,由统计学家R.A.Fisher整理,包含3个鸢尾花品种,每个品种50个样本,共150条观测。记录4个指标:花萼长度、花萼宽度、花瓣长度、花瓣宽度。是统计学经典数据集。
sub <- iris[iris$Species=="setosa" & iris$Petal.Length>1.4,]
sub$area <- sub$Petal.Length * sub$Petal.Width
hist(iris$Petal.Length,col="lightblue")
boxplot(Petal.Length~Species,data=iris)
plot(iris$Petal.Length,iris$Petal.Width)
R的基础安装只自带基础核心函数(mean()、plot()、data.frame()等),能完成最基础的计算和绘图。
R包(Package)就是别人写好、打包分享的代码集合,里面封装了大量现成函数、数据集、模板,不用我们从零手写代码。
全世界科研人员、统计开发者贡献了上万个开源R包,是R语言最强大的优势。
本节课后面要使用的
dplyr(数据清洗)、ggplot2(绘图),就是两个最经典、学术界广泛使用的R包。
安装 install.packages() 和加载
library()
安装包:install.packages()
只需要电脑第一次使用这个包的时候运行一次。从网络 CRAN 仓库,把包下载安装到你的电脑本地。联网才能运行;重装R、换电脑之后,需要重新安装。
方式1:代码安装(推荐,写进脚本方便复现)
# 安装dplyr和ggplot2,清华镜像加速(国内推荐)
install.packages(c("dplyr", "ggplot2"), repos = "[https://mirrors.tuna.tsinghua.edu.cn/CRAN/](https://mirrors.tuna.tsinghua.edu.cn/CRAN/)")
方式2:RStudio可视化界面点击安装(图形操作,新手友好)
dplyr, ggplot2(多个包用英文逗号隔开)Install dependencies(自动一并安装依赖包,建议勾选)Install from 保持默认:CRAN小提示:图形界面安装本质底层还是调用install.packages();图形操作不会写入脚本,换电脑/重装R时,操作步骤无法复用。科研和作业优先使用代码方式。
加载包:library()
每次打开RStudio、新开脚本,都要重新运行。
作用:把已经安装在电脑里的包“激活”,让R识别这个包里的函数。不需要联网;只安装不加载,函数无法使用。
注意:
install.packages()里面;library()写包名一般不加引号。install.packages("dplyr") # 安装:需要引号
library(dplyr) # 加载:不需要引号
tidyverse
是R语言一套现代数据科学工具集,核心思想是整洁数据(tidy
data):每行一条观测、每列一个变量。tidyverse并不是单一R包,而是包含dplyr(数据清洗)、ggplot2(可视化)、tibble等一系列配套包的集合。
传统原生R语法诞生较早,写法灵活但风格不统一,筛选、新增变量的代码可读性较差;tidyverse设计目标是代码更贴近人类自然语言,代码阅读顺序和思考数据处理的逻辑顺序保持一致,在社科、统计、生物等领域被广泛使用。
优势:
管道符号
%>%:把上一步的结果直接传递给下一个函数,减少大量临时变量,代码由上到下顺序阅读,逻辑连贯。
语法统一:dplyr系列动词(filter筛选、mutate新增变量、select选列)命名直观,新手更容易读懂。
和ggplot2无缝联动,数据处理+绘图一套体系。
说明:原生R语法和tidyverse没有绝对好坏。原生R是基础,理解底层原理;tidyverse适合快速、清晰地完成数据清洗与可视化,也是现在学术论文数据分析非常主流的写法。(老师更希望大家能够接受tidyverse风格,这样才体现出我们的‘后发优势’,虽然原生R风格也不错)
library(dplyr)
library(ggplot2)
# 优雅数据处理:筛选花瓣长度>1.5,新增长宽比变量,查看前几行
iris %>%
filter(Petal.Length>1.5) %>%
mutate(ratio = Petal.Length/Petal.Width) %>%
head()
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species ratio
## 1 5.4 3.9 1.7 0.4 setosa 4.250000
## 2 4.8 3.4 1.6 0.2 setosa 8.000000
## 3 5.7 3.8 1.7 0.3 setosa 5.666667
## 4 5.4 3.4 1.7 0.2 setosa 8.500000
## 5 5.1 3.3 1.7 0.5 setosa 3.400000
## 6 4.8 3.4 1.9 0.2 setosa 9.500000
# 优雅绘图:不同品种鸢尾花花瓣长度箱线图
ggplot(iris,aes(x=Species,y=Petal.Length,fill=Species))+
geom_boxplot(alpha=0.6)+
theme_bw()
管道 %>% 的快捷键:Ctrl + Shift + M