注意事项:

如何设置相关的主题?Tools – Global Option
| 1️⃣ Script(左上) | Ctrl+Enter | |
| 2️⃣ Console(左下) | ||
| 3️⃣ Environment / History(右上) | ||
| 4️⃣ Files / Plots / Packages / Help(右下) |
| 运行选中代码 | Ctrl + Enter |
| 运行全部代码 | Ctrl + Shift + Enter |
| 保存脚本 | Ctrl + S |
| 清空环境变量 | |
| 注释/取消注释代码 | Ctrl + Shift + C |
<- | Alt + 减号 |
| 快速查看帮助文档 | F1 |
Tools + Keyboard Shortcuts Help可以查看所有的快捷键工作路径 = R默认读写文件的文件夹。当你用
read.csv()或saveRDS()读写文件时,如果没写完整路径,R就会在工作路径中查找或保存文件。
方法1:通过 RStudio 菜单设置
getwd()# 查看当前工作路径setwd()# 设置工作路径
方法2:通过 RStudio 菜单设置
操作路径:Session → Set Working Directory → Choose Directory… 选择目标文件夹即可。
# 内置数据iris <- irisdemo <- irisdemo <- iris[,3:5]demo <- head(iris,50)demo <- iris[1:60,]demo <- iris[1:60,3:5]write.csv(demo,"data.csv")write.csv(demo,"data.csv", row.names =FALSE)# 相对路径的导出/适合大项目dir.create("data", showWarnings =FALSE)write.csv(demo,"data/data.csv", row.names =FALSE)
library(readxl)# 读取第1个sheetdf_xlsx <- read_excel("data.xlsx",sheet =1,# 这是导入第一个sheet,或者也可以 sheet = "Sheet名"na ="NA")# NA值定义
library(haven)# SPSSdf_spss <- read_sav("data.sav")# Statadf_dta <- read_dta("data.dta")# SASdf_sas <- read_sas("data.sas7bdat")
# RDS单对象saveRDS(demo,"data.rds")df_rds <- readRDS("data.rds")# RData可含多个对象save(data, demo, iris, file ="data.Rdata")load("data.Rdata")
| 向量(Vector) | c(1, 2, 3)c("A","B","C") | ||
| 矩阵(Matrix) | matrix(1:6, nrow=2, ncol=3) | ||
| 数据框(Data Frame) | data.frame(ID=1:3, Age=c(25,30,35)) | ||
| 列表(List) | list(a=1:3, b=c("A","B"), c=df) |
Vector → Matrix → Data Frame → List ↑ ↑ (同类型二维) (多类型二维)
| data.frame | ||
| matrix / data.frame/list | ||
| list | ||
| vector |
str(data)class(data)# 查看数据的类型和大致结构
可以在Rstudio中查看相关的数据内容
# 向量PL <- iris$Petal.LengthPW <- iris$Petal.WidthSpecies <- iris$Species# 矩阵mat <- cbind(PL, PW, Species)class(mat)# 数据框dataframedf <- data.frame(PL, PW, Species)class(df)# dataframe再创建的时候可以命名df1 <- data.frame(Petal.Length = PL,Petal.Width = PW,Species = Species)
先想好要做什么,再去想怎么实现你想的功能这里只介绍基本常用的功能
# 在之前已经讲了一些数据框的基本操作iris <- irisdemo <- iris[,3:5]demo <- head(iris,60)demo <- iris[1:60,]demo <- iris[1:60,3:5]#
# R内置数据集 irisdata(iris)# 查看前几行数据head(iris)# 查看后几行tail(iris)# 查看行列数dim(iris)# 150行 5列#只查看行数(有时候可以用来作为计算,有用后面会提到)nrow(iris)# 查看列名names(iris)colnames(iris)# 查看结构与类型str(iris)class(iris)
# 访问单列iris$Species# 多列iris[,c("Sepal.Length","Sepal.Width")]# 按行列索引取值(第1行第3列)iris[1,3]# 按条件筛选subset(iris, Species =="setosa")# 筛选多个条件subset(iris, Species =="setosa"& Petal.Length >1.4)
# 添加新列:花瓣面积iris$Petal.Area <- iris$Petal.Length * iris$Petal.Width# 删除列(用 NULL)iris$Petal.Area <-NULLiris <- iris[,-2]
# 基本统计summary(iris)# 计算平均花瓣长度mean(iris$Petal.Length)# 按物种分组求均值aggregate(Petal.Length ~ Species, data = iris, mean)
# 按花瓣长度升序排序iris_sorted <- iris[order(iris$Petal.Length),]# 按花瓣长度降序iris_sorted_desc <- iris[order(-iris$Petal.Length),]# 筛选花瓣长度大于5的样本subset(iris, Petal.Length >5)
# 选出前10行3列iris_sub <- iris[1:10,1:3]# 随机抽取样本set.seed(123)iris_sample <- iris[sample(nrow(iris),5),]
library(dplyr)# 前几行`setosa`中花瓣/花萼比例最高的样本。iris %>%filter(Species =="setosa")%>%select(Sepal.Length, Petal.Length)%>%mutate(Ratio = Petal.Length / Sepal.Length)%>%arrange(desc(Ratio))%>%head()
subset()[ ] | filter() | |
[ , c()] | select() | |
iris$new <- ... | mutate() | |
order() | arrange() | |
aggregate() | group_by()summarise() |
本章内容参考R for Data Science (2e)[https://r4ds.hadley.nz/];此外,也可以参考 https://r-graph-gallery.com/ 网站和ggplot2的官方文档[https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf]本人认为,微信公众号的搜一搜功能是最好的R绘图参考数据库!大家可以多用用。
# 注意:只需要在首次使用时安装if(!require("tidyverse")) install.packages("tidyverse")if(!require("palmerpenguins")) install.packages("palmerpenguins")if(!require("ggthemes")) install.packages("ggthemes")
除了 tidyverse,还需要使用到 palmerpenguins 包,其中包括包含帕尔默群岛三个岛屿上企鹅身体测量的数据集,以及 ggthemes 包,用于提供颜色搭配和主题搭配。
library(tidyverse)# 包含ggplot2library(palmerpenguins)# 企鹅数据集library(ggthemes)# 扩展主题view(penguins)
在开始学习前,我们先思考几个关键问题:
ggplot(data = penguins,mapping = aes(x = flipper_length_mm, y = body_mass_g))+geom_point(aes(color = species, shape = species))+geom_smooth(method ="lm")+labs(title ="Body mass and flipper length",subtitle ="Dimensions for Adelie, Chinstrap, and Gentoo Penguins",x ="Flipper length (mm)", y ="Body mass (g)",color ="Species", shape ="Species")+scale_color_colorblind()
ggplot2核心语法├─ 数据层 (data)├─ 映射层 (aes)├─ 几何对象 (geom_*)├─ 统计变换 (stat_*)├─ 坐标系 (coord_*)├─ 分面系统 (facet_*)└─ 主题系统 (theme_*)注释系统(annotate)
# 基础图层base_plot <- ggplot(data = penguins,mapping = aes(x = flipper_length_mm, y = body_mass_g))# 添加几何对象scatter_plot <- base_plot +geom_point(aes(color = species, shape = species), size =3, alpha =0.8)+geom_smooth(method ="lm", se =FALSE, color ="black")# 美化设置final_plot <- scatter_plot +labs(title ="企鹅身体形态关系研究",subtitle ="基于帕尔默群岛企鹅观测数据",x ="鳍肢长度 (mm)",y ="体重 (g)",caption ="数据来源:palmerpenguins包")+scale_color_colorblind()+theme_economist()# 使用ggthemes的经典主题print(final_plot)
如何可视化变量的分布取决于变量的类型:分类或数值
ggplot(penguins, aes(x = species))+geom_bar()ggplot(penguins, aes(x = fct_infreq(species)))+### 根据条形的频率对条形进行重新排序geom_bar()
# 直方图,关键参数 binwidthggplot(penguins, aes(x = body_mass_g))+geom_histogram(binwidth =200)ggplot(penguins, aes(x = body_mass_g))+geom_histogram(binwidth =20)ggplot(penguins, aes(x = body_mass_g))+geom_histogram(binwidth =2000)# 密度图(生信中用的很多)很多图是根据这个的变种做出来的ggplot(penguins, aes(x = body_mass_g))+geom_density()
# 箱线图ggplot(penguins, aes(x = species, y = body_mass_g))+geom_boxplot()# + geom_violin() + geom_jitter()# 密度图ggplot(penguins, aes(x = body_mass_g, color = species))+geom_density(linewidth =0.75)
# 堆叠柱状图用的最多也最实用ggplot(penguins, aes(x = island, fill = species))+geom_bar()ggplot(penguins, aes(x = island, fill = species))+geom_bar(position ="fill")
ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g))+geom_point()
ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g))+geom_point(aes(color = species, shape = island))ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g))+geom_point(aes(color = species, shape = species))+facet_wrap(~island)
| 函数名称 | 描述 |
|---|---|
geom_blank | |
geom_curve | |
geom_path | |
geom_polygon | |
geom_rect | |
geom_ribbon | |
geom_abline | |
geom_hline | |
geom_vline | |
geom_segment | |
geom_spoke | |
geom_area | |
geom_density | |
geom_dotplot | |
geom_freqpoly | |
geom_histogram | |
geom_qq | |
geom_bar | |
geom_label | |
geom_jitter | |
geom_point | |
geom_quantile | |
geom_rug | |
geom_smooth | |
geom_text | |
geom_col | |
geom_boxplot | |
geom_violin | |
geom_count | |
geom_contour | |
geom_bin2d | |
geom_density2d | |
geom_hex | |
geom_line | |
geom_step | |
geom_crossbar | |
geom_errorbar | |
geom_linerange | |
geom_pointrange | |
geom_map | |
geom_raster | |
geom_tile |
颜色可以平时收集不同的色卡,也可以直接用配色的包这里推荐一个色卡

install.packages("MetBrewer")install.packages("devtools")devtools::install_github("BlakeRMills/MetBrewer")
色卡参考上图的名称,以下是官方提供的使用示例,颜色代码的本质是一个包含各种颜色16进制代码或者名称的vector向量 c("red","blue"):
ggplot(data=iris, aes(x=Species, y=Petal.Length, fill=Species))+geom_violin()+scale_fill_manual(values=met.brewer("Greek",3))ggplot(data=iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species))+geom_point(size=2)+scale_color_manual(values=met.brewer("Renoir",3))ggplot(data=iris, aes(x=Species, y=Sepal.Width, color=Sepal.Width))+geom_point(size=3)+scale_color_gradientn(colors=met.brewer("Isfahan1"))
font_custom <-function(base_size =12){theme(axis.text = element_text(size = base_size +4),# 坐标轴文字调节axis.title = element_text(size = base_size +6),# 坐标轴标题plot.title = element_text(size = base_size +8,# 主标题face ="bold",hjust =0.5),legend.text = element_text(size = base_size +2),# 图例文字legend.title = element_text(size = base_size +4)# 图例标题)}
theme(# 显示顶部和右侧轴线axis.line.x.top = element_line(color = line_color,size = line_size),axis.line.y.right = element_line(color = line_color,size = line_size),panel.border = element_blank(),# 隐藏默认panel边框scale_x_continuous(#limits = c(0,10),expand =c(0.02,0)),# 控制轴两侧留白scale_y_continuous(#limits = c(0,10,expand =c(0.02,0))
labs(title ="Penguin Morphology Relationship",subtitle ="Palmer Station Antarctica",x ="Flipper Length (mm)",y ="Body Mass (g)",color ="Penguin Species",# 图例标题shape ="Penguin Species")
legend_custom <-function(){theme(legend.position ="bottom",# 图例位置legend.box ="horizontal",# 图例排列方向legend.background = element_blank(),# 清除背景legend.key = element_blank()# 清除图例键背景)}
# pdf格式,矢量图,可编辑,强烈推荐ggsave(filename = paste0(base_name,".pdf"),#在这里给图片命名plot = p,device = cairo_pdf,path = output_dir,width =8,height =6,useDingbats =FALSE)## pdf 格式的图片不用设置dpi,因为是矢量图,以下tiff和png都是需要设置dpi的# 保存为TIFF格式(论文出版),文件较大,不是很推荐,其实不是很清晰ggsave(filename ="plot.tiff"),#在这里给图片命名plot = p,device ="tiff",path = output_dir,dpi =600,# dpi 一般期刊要求300以上,我一般选600width =17.4,# 根据自己的图片调height =12,units ="cm",compression ="lzw"# 无损压缩)# 保存为PNG格式,我一般保存pdf和png双格式,这个格式非常清晰,且占用空间极小,适合用于PPT的制作,非常推荐ggsave(filename ="plot.png"),#在这里给图片命名plot = p,device ="png",path = output_dir,dpi =600,width =2400,# 像素单位,自己调一下height =1600,units ="px",bg ="white"# 设置背景色(透明背景用"transparent"),默认好像是透明色)
在提交论文前,请检查:
实际上,代码语言本质上只是一个工具。你真正需要掌握的,并不是“写代码”本身,而是如何利用代码去解决问题。如果长期停留在机械复现他人代码、反复照抄示例的阶段,很容易陷入“看似很努力,实则没有进步”的困境。
在这一期课程中,我会专门和大家讲一件越来越绕不开的事情:如何正确地使用大语言模型(LLM)来辅助生成代码。
正如我之前反复强调的,大语言模型的使用门槛极低。只要你愿意输入一句话,它就可以给你生成上百行、甚至上千行的代码。但问题恰恰出在这里——代码是写出来了,但你并不知道它在做什么,更无法判断它是否在“正确地做你想做的事”。久而久之,这反而会成为你学习一门编程语言的最大阻碍。
我对此印象非常深刻。有一次,一位研一的师弟来找我,导师让我带他“简单入个门”。我当时的建议很朴素:先学 R,随便看看入门视频,遇到问题就用 ChatGPT 写代码即可。
两天后我去他工位看了一眼,发现他已经开始“赛博炼丹”。他直接给 GPT 抛出了一个极其宏大的研究目标,GPT 回了他一段结构复杂、依赖繁多的代码;他把代码原封不动复制运行,报错后再把报错完整粘给 GPT;GPT 又在原代码上打了一堆补丁;然后继续报错……如此循环,最后代码依旧没跑通,他本人也彻底陷入了挫败状态。
后来我仔细复盘了一下,这件事的核心问题并不在于 GPT,也不在于 R,而在于一句话:
他根本不知道自己“具体想做什么”。
只有当你明确了“我要完成什么目标”,你才会有动力、也有方向去学习新的技能,并判断一段代码到底是“对我有用”还是“看起来很厉害”。
学习 R 也是完全一样的逻辑。你不是在学一门语言,而是在借助一门语言完成任务。
R 和 Python 在能力边界上远比大多数初学者想象得要宽,它们几乎可以完成你在科研与临床研究中能想到的所有分析任务。因此,真正困难、也真正重要的,并不是语法本身,而是:
如何把你的研究目标,拆解成清晰、可执行、可被代码实现的需求。
基于我这些年在临床预测模型教学与科研实践中的经验,我将 R 语言在临床预测模型中的“需求” 总结为以下几个核心类别。你可以把它们理解为:你向大语言模型提问、向代码发号施令时,最常用的“问题模板”。
head()/str() 或 3 行样例。你是一个擅长R语言的专家,我现在有一个名为 df 的数据框(粘贴你的数据的head(df))(示例:大约 120 行、至少包含两列:分组变量 Group=“A/B/C”和连续数值变量 QoR15_24h),想用 R(优先 ggplot2,可用 ggpubr)画一张可用于论文/汇报的箱线图:横轴为 Group,纵轴为 QoR15_24h;要求同时叠加抖动散点以展示个体分布,箱线图不显示离群点(避免遮挡),并在图上标注统计学比较结果(先做三组总体差异检验 Kruskal-Wallis,再做两两 Wilcoxon 检验并进行 BH 校正,标注为格式化 p 值或星号均可);请在代码里先处理常见问题(将 Group 设定为因子并固定顺序 A、B、C;将 QoR15_24h 强制为数值型并剔除 NA),然后生成图对象并保存为矢量格式 PDF(文件名 fig_boxplot_QoR15_24h.pdf,尺寸约 6×4 inch);整体风格简洁,配色采用低饱和度的顶刊适用配色,标题与坐标轴标签清晰,输出为一段可直接运行的完整 R 代码。