在读取一行数据之前,应该先考虑下重复数据管理的通用规则,不改写原始数据。原始文件视为只读,保留原始文件名字并说明来源,是一个好办法。
软件配置
几个包:
代码语言:javascript复制install.packages(c("rio","readr","data.table","feather","WDI"))
关于数据I/O的高级技巧
- R语言自己的文件格式是.Rds,可以使用readRDS()与saveRDS()函数导入与导出,是一种速度与空间存储都什么高效的格式。
- 使用rio包的import()能导入各种格式的数据,避免加载特定格式库的麻烦。
- 对于高效导入大文本文件,使用readr或data.table与read.table()相当。
- 使用file.size()与object.size()跟踪文件与R对象的大小,以便在过大之前提前预防。
使用rio的通用数据导入
多功能包,名副其实,提供简单易用和计算高效的函数,其目标是简化数据导入导出过程。R的数据导入导出手册中有些函数已经过时了,比如WriteXLS包,且很难学习。rio包可以处理的格式包含:.csv, .feather, .json, .dta, .xls, .xlsx和谷歌在线表格。其无需指定可选的format参数,另外可以从网络下载数据。json格式的导入还可以使用jsonlite和和geojasonio包。
代码语言:javascript复制library("rio")
x <- import("mtcars.csv")
y <- import("mtcars.rds")
z <- import("mtcars.dta")
export(mtcars, "mtcars.csv")
export(mtcars, "mtcars.rds")
export(mtcars, "mtcars.xls")
纯文本格式
.csv格式是最常见格式,有三种读入R的方法:1)基础R的read.csv(),2)fread() 里data.table方法3)较新的readr包里read_csv()函数。虽然有所差异,但是交叉兼容。read.csv()是read.delim()和read.table()的封装。readstata13包是专门读取Stata13以上版本的.dta文件而开发的。对于小于1M的数据,read.csv()比read_csv()要快,然而fread()比两个都快,如果是更大的数据,read_csv()和data.table比read.csv()快5倍左右。
fread()与read_csv()的差异
readr与基础read_()一样,是基于前1000行而不是所有行来决定每个变量的类。使用readr的话,会将违规数值转换成NA,而fread()会自动将它认为是数值的列转化成字符,fread()另一特征是可以使用列名或索引来设置select参数,从而有选择的读取列。总的来说,三者在读入数据的差异超过了代码执行的时间,与基础R相比,其他两个的速度提升是一定程度的牺牲健壮性为代价的。在基础R中stringAsFactors=TRUE时才会将字符不转化为因子,而fread()和read_csv()函数默认返回字符型。read_()生成tbl_df类,而fread()产生data.table()类对象,没有实际差别,处理稍有不同,除非trbble包被加载。
R外预处理文本
读入一个4G的文本文件,会耗尽16G的内存RAM,可以使用shell命令split等分割文件,采用数据库是另外一个解决方案。split -b100m bigfile.csv
# -b100m意思是分割成100m每个的文件。
二进制文件格式
纯文本格式有局限性,缺少类型安全,限于表格,限制 了数值精度,以二进制保存,可以减少读写时间和文件大小。
R自带的文件格式:Rds和Rdata
save()为Rdata是应用最广泛的,函数功能类似save.img()和save.imge()。saveRDS()函数应用相对较少,作者推荐这个,保存R对象更加简洁,readRDS()更加灵活,结果对象可赋值任何名字。使用这个是个好习惯,强制指定对象名字。
feather文件格式
这是为了R语言与Python程序员协作而设计的格式,速度快,轻量、保存数据框是与语言无关。
二进制文件的基准测试
Rds文件表现最好,磁盘空间仅仅是csv文件的1/4多点,feather格式大约是csv的一半。读入,比read.csv()快十倍左右,写feather更快,比write.csv()快十倍,而saveRDS()仅仅快1.2倍。
Protocol Buffers格式
谷歌的,RProtoBuf包提供了R接口。
从互联网获得数据
download.file()函数和zip()可以批量下载和解压数据。read_csv()也可以直接读取网址中的数据,但是如果下载失败需要重复下载。
代码语言:javascript复制fileUrl <- "http://www.newcl.org/data/zipfiles/a1.zip"
download.file(fileUrl, destfile = "a1.zip") #下载并保留原始文件名
unzip('a1.zip', exdir="data")
file.remove("1.zip") #移除原文件防止空间浪费
rOpenSci是众多帮助下载和导入数据的包,下面的代码是通过WDI包(不被rOpenSci支持),访问世界银行下载的交通CO2排放的数据:
代码语言:javascript复制> library("WDI")
> WDIsearch("CO2")
indicator name
[1,] "EN.ATM.CO2E.CP.KT" "CO2 emissions from cement production (thousand metric tons)"
[2,] "EN.ATM.CO2E.EG.ZS" "CO2 intensity (kg per kg of oil equivalent energy use)"
[3,] "EN.ATM.CO2E.FF.KT" "CO2 emissions from fossil-fuels, total (thousand metric tons)"
[4,] "EN.ATM.CO2E.FF.ZS" "CO2 emissions from fossil-fuels (% of total)"
[5,] "EN.ATM.CO2E.GDP" "CO2 emissions, industrial (kg per 1987 US$ of GDP)"
[6,] "EN.ATM.CO2E.GF.KT" "CO2 emissions from gaseous fuel consumption (kt) "
[7,] "EN.ATM.CO2E.GF.ZS" "CO2 emissions from gaseous fuel consumption (% of total) "
[8,] "EN.ATM.CO2E.GL.KT" "CO2 emissions from gas flaring (thousand metric tons)"
[9,] "EN.ATM.CO2E.KD.87.GD" "CO2 emissions, industrial (kg per 1987 US$ of GDP)"
CO2_transport <- WDI(indicator = "EN.CO2.TRAN.ZS")
> head(CO2_transport)
iso2c country EN.CO2.TRAN.ZS year
1 1A Arab World NA 2020
2 1A Arab World NA 2019
3 1A Arab World NA 2018
4 1A Arab World NA 2017
5 1A Arab World NA 2016
6 1A Arab World NA 2015
最好在代码中对数据来源做些简单注释,方便代码对自己和他人的可用性。与Web页面交互的两个包是httr和RCurl包,httr有相对友好的用户接口(没有图形界面的),RCurl是更接近底层。
访问包中的数据
示例数据可以用如下方式查看:data(package="dplyr")
Data sets in package ‘dplyr’:
band_instruments Band membership
band_instruments2 Band membership
band_members Band membership
starwars Starwars characters
storms Storm tracks data
原始数据通常位于R包的extdata目录中,system.file()函数输出具体包的文件路径:
代码语言:javascript复制> list.files(system.file("extdata",package="readr"))
[1] "challenge.csv" "epa78.txt" "example.log" "fwf-sample.txt" "massey-rating.txt"
[6] "mtcars.csv" "mtcars.csv.bz2" "mtcars.csv.zip"
可以通过下图的方式,按tab键就可以查看文件夹结构: