R语言数据加载全攻略:从路径设置到CSV/Excel/RDS
2026/9/23 7:54:34 网站建设 项目流程

1. 加载数据前的头等大事:先把工作目录和项目结构理顺

很多人学R语言,装好软件之后第一件事就是敲read.csv("xxx.csv"),然后报错 “cannot open file”,或者 “No such file or directory”。这时候十有八九不是文件有问题,而是你的工作目录根本不在文件所在的文件夹里。这个坑我在带新人时见过太多次,所以把加载数据这件事写进系列第二篇,必须先花一整节把工作目录讲透。

R语言在启动时默认的工作目录,一般是你安装R时设定的那个路径,或者是打开RStudio时默认的目录。它就像是你在命令行里所处的“当前位置”,你写的相对路径(比如"data/raw/iris.csv")都是相对于这个位置去找的。如果你在D盘打开了一份数据文件,但R的工作目录还在C盘某个角落,那再怎么写相对路径也是白搭。

验证当前工作目录特别简单,一条命令就行:

getwd()

想修改工作目录,有两种常用方式:

# 方式一:手动指定路径 setwd("C:/Users/你的用户名/Documents/RProject/data") # 方式二:弹窗选择文件夹 choose.dir()

这里必须提醒一个Windows用户极易踩的坑:路径分隔符一定要用正斜杠/或者双反斜杠\\,不要用单个反斜杠\。因为在R字符串里反斜杠是转义字符,"\d"会被解析成不认识的转义序列,轻则路径找不到,重则直接报错。

不过,我自己实际干活时基本不靠setwd(),而是直接建RStudio项目(.Rproj)。只要打开某个.Rproj文件,RStudio就会自动把这个项目所在目录设为工作目录,所有相对路径都是从项目根目录开始算。配合here包还能更省心,写here("data", "raw", "iris.csv")这种写法,不管项目搬到哪里都不会路径失效。

提示:用setwd()写死绝对路径,换个电脑或者把项目分享给别人,路径大概率就失效了。建议从一开始就养成“项目根目录 + 相对路径”的思维习惯。

另外,文件的命名也建议别用中文和空格。R本身对中文路径的支持不算差,但不同系统的兼容性差异很大,尤其在readr这种底层用C++实现的包里,中文路径偶尔会出怪问题。老老实实用英文、数字、下划线命名,能省掉无数莫名奇妙的报错。

2. 先跟R语言自带的“试用装”混个脸熟

在急着去读自己的数据之前,我强烈建议初学者先玩玩R内置的数据集。R自带几十个经典数据集,分布在datasets包里,装好R就有,不需要下载任何文件。它们的价值在于:格式规范、没有乱码、分好类,拿来练 hand 完全够用,非常适合理解“加载数据”之后那些数据结构相关的概念。

想看看自己能用的内置数据集有哪些,直接运行:

data()

会弹出一个列表,里面有irismtcarsAirPassengersChickWeight这些经典数据。加载方式很简单:

data(iris) # 加载鸢尾花数据集 data(mtcars) # 加载汽车测试数据

加载之后,右侧环境面板(Environment)里就能看到这几个数据集了。这时候你可以敲str(iris)head(iris)summary(iris)去感受一下“数据到底长什么样”。这一步虽然简单,但对于新手建立“数据 = 行列结构”的感性认识,特别重要。

还有一些数据集不在datasets包里,而是藏在其他包中。比如MASS包里的Boston房价数据,ggplot2包里甚至没有自带数据集但隔壁dplyr里常有。这类数据加载方式稍有不同:

# 先安装包 install.packages("MASS") # 加载包之后才能使用包内的数据 library(MASS) data(Boston)

这里要记住一个区别:library()是加载这个包到当前会话,包里的函数和数据才能直接调用;而data()只是“将某个包的数据集载入到全局环境”。如果你只调用了data(Boston)却没先library(MASS),多数情况也会自动找到这个包并加载,但偶尔会提示需要手动安装,所以保险起见,先把包加载了再取数据。

用内置数据集练手有个天然好处:社区资料多,网上几乎所有R教程都用这些数据跑示例。你在学习阶段遇到任何问题,拿着irismtcars去搜,很容易找到对应的讨论。换成自己的数据去搜,很多时候别人根本没法复现你的问题。所以学习期老老实实跟“试用装”混熟,比一开始就拿真实数据硬刚要平滑得多。

3. 最常见的数据加载实操:CSV与文本文件

CSV算得上是数据交换的“万国语言”,几乎所有数据工具都能导出CSV,R也不例外。这一节我会把read.csv和它的进阶版readr::read_csv仔细讲一遍,因为大多数人学R后加载的第一份外部数据就是CSV。

3.1 基础版:read.csv / read.table

read.csv是R基础包里最经典的文本文件读取函数。先看我最常用的写法:

df <- read.csv("data/iris.csv", stringsAsFactors = FALSE, encoding = "UTF-8")

这行代码里几个参数背后的含义,值得逐一拆解:

  • "data/iris.csv"是文件路径。我这里用的是相对路径,前提是你已经建好了RStudio项目,且data文件夹放在项目根目录下面。
  • header = TRUE是默认值,表示把第一行当作列名。如果文件没有列名,需要显式改成header = FALSE,R会自动生成V1V2这种列名。
  • stringsAsFactors = FALSE是我个人的执念。R 4.0之前,读进来的字符串默认会转成因子(factor),而不是普通字符(character)。因子在做统计建模时确实有用,但它会悄悄改变字符串的排序、比较、子集选取等行为。我几乎总是在数据清洗阶段希望它们是字符型而不是因子,所以会显式关掉这个转换,等真正需要因子化时再用as.factor()手动转。
  • encoding = "UTF-8"是中文数据最常见的坑源。Windows系统下,很多CSV文件是ANSI(GBK)编码,而RStudio默认按UTF-8读取,一旦编码不匹配,中文内容就会变成一串乱码。

如果你不确定文件编码,一个土办法是用记事本打开CSV另存为,编码选UTF-8,然后再用R读取。或者用read.csv时先读几行看效果,乱码就换编码重读。

如果文件路径里有特殊字符、或者你不想手输路径,也可以用文件选择框:

df <- read.csv(file.choose())

file.choose()会弹出系统自带的选择文件窗口,选文件就行。这种方式适合临时读一次,不适合写进脚本里重复执行——总不能每次跑代码都让人手动选文件吧。

3.2 进阶版:readr包的read_csv

基础包的read.csv够用,但它有几个小毛病:第一,读取大文件速度不够快;第二,自动识别列类型偶尔会出错,比如明明整列是整数却被读成数值型;第三,对编码和格式的处理比较“笨重”。

readr包(Tidyverse系)就是来解决这些问题的。它读取速度明显快于基础函数,而且对列类型的判定更智能,还支持把列类型规范强制指定:

# 安装并加载readr install.packages("readr") library(readr) df <- read_csv("data/iris.csv", col_types = cols( Sepal.Length = col_double(), Species = col_character() ))

col_types这个参数其实是个双刃剑。好处是你可以精确指定每一列是什么类型,坏处是如果你指定的类型和实际数据不符,它不会报错而是转成NA,导致数据悄悄丢失。所以我的建议是:初次读取时不指定col_types,让它自动判断,然后观察read_csv打印出的列类型摘要,如果发现哪列类型不对,再针对性地指定。这个过程既能让你掌握数据,又能避免手动指定翻车。

另一个readr贴心的点是,它在读取时会打印每列的猜测类型(比如chrdblint),你一眼就能发现问题列。基础包的read.csv就没有这种“报告感”,读错了也不吭声。

3.3 其他文本格式:read.table、read.delim

read.table是更通用的文本读取函数,可以自定义分隔符。read.csv本质上就是read.table的一个特殊封装,相当于固定了分隔符为逗号、header = TRUE等默认参数。如果你处理的是制表符(Tab)分隔的文件,常见扩展名是.txt.tsv,用:

df <- read.delim("data/raw_data.txt", sep = "\t")

sep参数里,"\t"表示制表符,","是逗号,";"是分号。欧洲某些地区导出的CSV经常用分号作分隔符,用read.csv读会变成只有一列,这时候显式指定sep = ";"就行。

3.4 大CSV文件读不动怎么办

如果你的CSV有几百MB甚至几个GB,read.csvread_csv都会明显吃力。这时候我推荐直接上data.table包的fread(),它在读超大文件时性能极好,而且调用极其简洁:

install.packages("data.table") library(data.table) df <- fread("data/big_data.csv")

fread会自动识别分隔符、自动判断列类型,读取速度和内存使用都特别优秀。处理1GB左右的CSV,read.csv可能要等一两分钟,fread十几秒左右就能读完。它的返回结果是data.table类型,和data.frame虽然用法接近但有些细节不同,不熟悉的话可以先用setDF(df)把它转回普通数据框,或者直接用方括号语法操作data.table,熟悉之后效率比数据框还高。

提示:遇到那种只报错 “cannot open connection” 的情况,绝大多数是路径问题。先getwd()看看当前位置,再核对路径拼写,比反复改代码参数更靠谱。

4. Excel数据也别慌:readxl包能解决大部分需求

中文办公环境里,Excel(.xlsx)比CSV更常见。很多业务端的同事导数据,默认就是给你一个Excel文件。R基础包没有内置读取Excel的函数,必须靠第三方包。这里最常用的是readxl

install.packages("readxl") library(readxl) # 读取第一个sheet df <- read_excel("data/report.xlsx") # 指定读取第2个sheet df <- read_excel("data/report.xlsx", sheet = 2) # 按sheet名读取 df <- read_excel("data/report.xlsx", sheet = "汇总表")

readxl的特点是不依赖Java,安装简单,读取速度也快。它还会自动把Excel里的日期列转成日期类型,这个比很多老方法(比如xlsx包)更省心。

不过读Excel有个特别容易踩的坑:列名里有看不见的空格或特殊字符。Excel表格里的人喜欢写“销售额 ”(带空格)、“单价(元)”这种列名,读进R后这些空格和括号依然存在,直接操作时要么用反引号包裹,要么当场重命名。我的习惯是读完立刻统一改名:

colnames(df) <- c("sales", "price", "region")

如果遇到Excel里一个单元格里既有数字又有文字(比如“12,000元”),读取后R会默认把它当字符型,后续做计算就得先清洗。这时候可以用readr::parse_number()或者dplyr::mutate()清洗一下。

还有一个容易让人懵的情况:Excel里明明是标准日期,读进R后却变成了一个数字,比如45000这种。这是因为Excel内部把日期存储为从1900年1月1日起的序列号,某些读取方式不会自动转换。解决方案是读取的时候指定列类型:

df <- read_excel("data/report.xlsx", col_types = c("date", "text", "numeric"))

分别对应每一列的类型。不过要先明白文件有哪些列,不然类型对不上号。

如果你处理的Excel文件数量很多,或者里面有大量公式、图表、透视表,readxl只能读数据,其他内容不关心。这也够了,反正R做数据分析要的是单元格值本身,而不是Excel的展示样式。假如Excel本身结构特别复杂(合并单元格、列顺序乱、多级表头),建议让业务方先导出成CSV或者整理成规范的二维表,再做导入,省下的时间远大于沟通成本。

5. 高效率传递R数据:RDS与RData

CSV和Excel是给人看、给别的系统用的通用格式。但如果你只是想在R里面保存数据、下次继续用,或者把数据处理到一半的结果存下来共享给另一个R脚本,这类通用格式反而低效。原因有几个:CSV存不了因子水平、存不了日期格式、存不了列表列这种复杂结构;而且每次读取都要重新判定列类型,大文件读起来费时费力。

这时候推荐用R自己的原生数据格式——RDSRData(扩展名分别是.rds.RData)。它们能把R对象完整保存下来,包括类型、因子、日期、属性,读取速度也远快于CSV。

5.1 RDS:保存单个对象

# 保存 saveRDS(df, file = "data/cleaned_data.rds") # 读取 df2 <- readRDS("data/cleaned_data.rds")

saveRDS保存的是“一个R对象”,读取时你用任意变量名接住它——存进去叫df,读出来可以叫df2。这种灵活性在处理多个中间结果时特别方便。

5.2 RData:保存多个对象

# 保存多个对象 save(df1, df2, model_result, file = "data/workspace.RData") # 读取 load("data/workspace.RData")

load()会把所有对象按原来的名字加载到当前环境。比如你保存了df1df2,加载后它们就直接出现在环境里,不需要赋值。

这里有个细节需要提醒:saveRDS/readRDS适合保存单个结果对象,尤其是函数返回值的临时缓存;save/load适合批量保存和恢复工作空间。两者选谁都行,但别混用。另外,如果你要在多个R脚本之间传递同一个数据集,我更推荐RDS,因为它是“显式赋值变量”,不污染环境,也更容易看清楚数据流。

5.3 什么时候用RDS/RData,什么时候用CSV

我的经验是:中间数据用RDS,最终交付用CSV。中间数据是你自己脚本流水线上的半成品,用RDS能最高保真;而最后整理好的表格要发给别人、或者拿到其他系统里用,就必须导出通用格式。导出就是反向操作:

write.csv(df, "output/result.csv", row.names = FALSE)

row.names = FALSE这个参数经常有人忘,不关掉的话导出的CSV会多一列行号,打开Excel总是怪怪的。

6. 走向实战:其他常见数据来源

入门阶段掌握CSV、Excel、RDS基本够用,但实际项目里数据来源会五花八门。这里列出我工作中经常碰到的几种,以及对应的加载方案,大家按需求取用。

6.1 数据库:DBI + 对应驱动

R连接数据库的统一接口是DBI包,配合具体的数据库驱动。比如SQLite的加载很简单,不需要单独装数据库服务:

install.packages(c("DBI", "RSQLite")) library(DBI) con <- dbConnect(RSQLite::SQLite(), "data/my_database.db") df <- dbGetQuery(con, "SELECT * FROM orders") dbDisconnect(con)

如果是MySQL或PostgreSQL,驱动换成RMariaDBRPostgres,连接时加上主机、用户名、密码即可。数据库连接用完一定要dbDisconnect()断开,这和文件连接、网络连接是一个道理,不释放的话连接数会越积越多导致后续连不上。

6.2 JSON:jsonlite包

从Web API拉数据,返回格式基本是JSON。R处理JSON的标配是jsonlite

install.packages("jsonlite") library(jsonlite) df <- fromJSON("https://api.example.com/data")

fromJSON不只是能读URL,也能读本地JSON文件。JSON里面的嵌套结构会被自动展开成数据框,但嵌套太深时偶尔会变成列表列,这时候需要tidyr::unnest()进一步展开。

6.3 特定领域数据格式

有些领域使用的数据格式非常专一。用户热搜里提到的modelnet40和DICOM就是典型例子:前者是三维点云深度学习领域常用的公开数据集,加载它要用专门的ModelNet40相关工具或通过Python处理后转R格式;后者是医学影像标准格式,R里可以试试oro.dicom包,不过医学影像处理的主战场一般认为在Python这边。遇到这种极其专一的数据格式,我的建议是:先搜索有没有对应的R包;如果没有,就用R或者其他工具把它转成CSV/Parquet/RDS再进R。死磕“用R直接读一切”没必要,工具之间做转换本来就是数据工作的常态。

再比如NetCDF(.nc)这种气象海洋常用的科学数据格式,R里的处理主力是ncdf4包;如果只想快速查看结构,可以用tidync。这类二进制科学格式通常自带维度信息(经纬度、时间、变量),不是普通表格那种二维结构,读取后一般是长表或列表,需要多做一步整理。

6.4 网络与云存储上的数据

很多公开数据集是提供URL直链的。比如UC Irvine Machine Learning Repository里的数据集,read.csv可以直接传URL:

df <- read.csv("https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data")

读取网络数据前,务必确认网络环境稳定,并且注意数据提供方的使用条款。云存储(如AWS S3)上的文件可以先下载到本地临时目录,再用readRDSread_csv读取。

7. 加载之后的第一件事:给数据做个“体检”

数据加载成功不等于万事大吉。我见过不少人弹尽粮绝地把数据读进来了,然后转头就开始画图建模,结果图是出来了,图里的结论却因为数据加载时列类型被改掉而全是错的。所以必须养成读完之后马上检查数据的习惯。

体检三件套:

# 1. 看结构:每列的类型和前几个值 str(df) # 2. 看前几行:直观感受数据的“长相” head(df, 10) # 3. 看统计摘要:数值列的最小、最大、均值,因子列的频数 summary(df)

这三条命令能快速暴露大部分问题:列类型对不对,有没有明显缺失值,数值范围是否合理,有没有异常值。举个例子,summary(df)如果显示某列最大值是一万而其他都在几百以内,这个一万大概率是录入错误;日期列如果显示的是数字而不是Date类型,说明类型判断出了问题。体检阶段发现的问题,越早处理代价越小;处理完再做下一步分析,你会明显感觉后面的操作顺畅很多。

还有几个加载后常被忽略的检查点:

  • dim(df)查看行数和列数,确认和源数据一致。如果少了行,多半是读取时把某些行误当成了注释或跳过了。
  • colnames(df)查看列名,确保没有重复列名、空列名。
  • is.na(df)colSums(is.na(df))查看缺失值分布。

注意:数据体检是“加载数据”这个环节的收尾动作,也是“数据清洗”的起点。千万别把加载和清洗看成两件独立的事,它们实际是连在一起的。加载时的参数选择(比如stringsAsFactorsencoding)直接影响后面清洗的工作量。

8. 常见问题与排查技巧实录

做技术支持这些年,我收集了初学者在加载数据时最容易踩的几类问题,整理成一个速查表,方便大家遇到报错时对着排查。

现象可能原因解决方案
cannot open file工作目录不对 / 路径写错 / 文件名拼错getwd()查看当前目录,修正相对路径或使用绝对路径
中文变成乱码文件编码不是UTF-8改读文件时的encoding参数,或把文件另存为UTF-8编码
读进来只有一列分隔符不对read.csv改为read.delim,指定sep参数
字符串被读成因子忘记设置stringsAsFactors读取时显式stringsAsFactors = FALSE
数值列被读成字符列里有“1,000”或“12元”这类文本先读成字符,再用readr::parse_number()提取数字
日期变成一串数字Excel日期序列号未被转换read_excel里指定col_types = "date"
多出的X列名原数据没有列名,R自动生成读取时header = FALSE,或手动设置列名
大文件读取很慢用了基础包的read.csv改用data.table::fread()readr::read_csv()

再分享两个比较隐蔽的独家经验。

第一,读取Excel后列名里带着不可见字符。Excel表格制作时,有人会顺手在列名前后打上几个空格,肉眼根本看不出来,但用dplyr::select()时死活匹配不上。遇到这种情况,可以用names(df)打印列名,仔细看有没有空格;如果有,批量去掉:

names(df) <- trimws(names(df))

第二,Windows系统和R的路径反斜杠问题。RStudio里的自动补全提示路径时,有时候会给你\风格路径,直接复制去用容易出问题。更稳妥的办法是让R帮我们合并路径,不要手动拼字符串:

file.path("data", "raw", "iris.csv")

file.path会根据你当前的操作系统自动选择正确的分隔符。在RStudio里甚至可以直接高亮路径然后按键盘自动补全,实现“鼠标选择文件”的效果:打开一个文件后,用readr::read_csv会弹出文件选择窗口,这样可以避开手输路径的烦恼。

第三个经验是关于RStudio里那个“Import Dataset”按钮的。对新手来说,点按钮可视化导入确实方便,但我不建议长期依赖。按钮操作会生成一段代码放到Console里,但这段代码不会自动写进你的脚本。下次换数据、改路径,你还得重来一遍。学习的目的是形成可复现的脚本,所以哪怕开始慢,也尽量养成“在脚本里写read_csv()而不是点按钮”的习惯。

9. 我个人在数据加载这件事上的最后几点体会

练得多之后你会发现,加载数据本身并不炫酷,但它决定了后面所有分析的起点。数据加载错了,后面再漂亮的图表和模型都是空中楼阁。我自己的流程固定为:先getwd()确认位置,再用RStudio项目管理路径,读进来之后立刻str()+head()+summary()做快速体检,发现异常就当场处理。这套流程看似繁琐,但实打实地帮我挡掉过很多次“后面图表结论全错”的惨剧。

如果你刚开始学R,建议按这个顺序把今天的代码都敲一遍:内置数据iris、CSV导入、Excel导入、RDS保存读取,最后建一个RStudio项目把整个流程串起来。不要复制粘贴,手敲一遍和复制一遍的记忆效果差距非常大。数据加载这一关过了,后面做数据处理、可视化、建模都会顺很多。

最后再分享一个小技巧:写脚本时,文件读取和文件导出尽量放在脚本的最开头和最末尾,中间全放数据清洗和分析的逻辑。这样别人看你的脚本时,只看开头几行就知道输入是什么,看结尾几行就知道输出是什么,中间的逻辑再长也不会让人迷失方向。这个习惯在我带过的项目里,被验证为最能让脚本“可读、可复用、可交接”的做法。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询