§2.4 读、写数据文件
在应用统计学中,数据量一般都比较大,变量也很多,用上述方法来建立数据集并不可取. 上述方法适用于少量数据、变量的分析. 对于大量数据和变量,一般应在其他软件中输入(或数据来源是其他软件的输出结果),再读到R中处理. R语言有多种读数据文件的方法.
另外,所有的计算结果也不应只在屏幕上输出,而应当保存在文件中,以备使用. 这里介绍一些R软件读、写数据文件的方法.
§2.4.1 读纯文本文件
读纯文本文件有两个函数:一个是read.table()函数;另一个是scan()函数.
1. read.table()函数
read.table()函数读取表格形式的文件. 例如,"houses.data"存入某处的住宅数据,它是一个纯文本文件,并具有表格形式:
Price Floor Area Rooms Age Cent.heat 1 52.00 111.0 830 5 6.2 no 2 54.75 128.0 710 5 7.5 no 3 57.50 101.0 1000 5 4.2 no 4 57.50 131.0 690 6 8.8 no 5 59.75 93.0 900 5 1.9 yes
其中第一行为变量名称,也就是表头,后面的各行记录了每个房屋的数据. 第一列为记录序号,后面的各列为房屋的各项指标.
read.table()函数可读取数据的格式和结果如下:
> rt <- read.table("houses.data"); rt Price Floor Area Rooms Age Cent.heat 1 52.00 111 830 5 6.2 no 2 54.75 128 710 5 7.5 no 3 57.50 101 1000 5 4.2 no 4 57.50 131 690 6 8.8 no 5 59.75 93 900 5 1.9 yes
它的形式与文件"houses.data"相同.read.table()函数的返回值为数据框,也就是说,变量rt为数据框. 可通过测试函数is.data.frame()或class属性来确认这一点.
如果数据文件中没有记录序号的列,如"houses.data"文件具有以下形式:
Price Floor Area Rooms Age Cent.heat 52.00 111.0 830 5 6.2 no 54.75 128.0 710 5 7.5 no 57.50 101.0 1000 5 4.2 no 57.50 131.0 690 6 8.8 no 59.75 93.0 900 5 1.9 yes
则读取数据的命令需要改为:
> rt <- read.table("houses.data", header = TRUE)
也就是说明数据文件的第一行是表头,得到的结果与前一个命令相同.
read.table()函数的使用格式为: read.table(file, header = FALSE, sep = "", quote = "\"'", dec = ".", row.names, col.names, as.is = !stringsAsFactors, na.strings = "NA", colClasses = NA, nrows = -1, skip = 0, check.names = TRUE, fill = !blank.lines.skip, strip.white = FALSE, blank.lines.skip = TRUE, comment.char = "#", allowEscapes = FALSE, flush = FALSE, stringsAsFactors = default.stringsAsFactors(), fileEncoding = "", encoding = "unknown", text)
部分参数的名称、取值及意义如表2.8所示.
2. scan()函数
scan()函数直接读纯文本文件数据. 例如,"weight.data"文件保存了15名学生的体重,它是一个纯文本文件,其格式如下:
75.0 64.0 47.4 66.9 62.2 62.2 58.7 63.5 66.6 64.0 57.0 69.0 56.9 50.0 72.0
表2.8 read.table()函数中部分参数的名称、取值及意义
命令w<-scan("weight.data")是将文件中的15个数据读出,并为w赋值,此时,函数的返回值为一向量,即w为向量,大家可用is.vector()函数来验证这一点.
假设数据中有不同的属性,例如,纯文本数据文件"h_w.data"中的数据如下:
172.4 75.0 169.3 54.8 169.3 64.0 171.4 64.8 166.5 47.4 171.4 62.2 168.2 66.9 165.1 52.0 168.8 62.2 167.8 65.0 165.8 62.2 167.8 65.0 164.4 58.7 169.9 57.5 164.9 63.5 ... ... ... ... ... ... ... ... ... ...
为100名学生的身高和体重,其中第1、3、5、7、9列为身高(单位:cm),第2、4、6、8、10列为体重(单位:kg),命令
> inp <- scan("h_w.data", list(height = 0, weight = 0))
将数据读出,并以列表的方式赋给变量inp,其中height和weight为列表inp的元素名称.
如果不输入文件名,则scan()函数会直接从屏幕上读数据,如:
> x <- scan() 1: 1 3 5 7 9 6: Read 5 items > x [1] 1 3 5 7 9 > names <- scan(what = "") 1: ZhangSan LiSi WangWu 4: Read 3 items > names [1] "ZhangSan" "LiSi" "WangWu" scan()函数读文件的一般格式为: scan(file = "", what = double(), nmax = -1, n = -1, sep = "", quote = if(identical(sep, "\n")) "" else "'\"", dec = ".", skip = 0, nlines = 0, na.strings = "NA", flush = FALSE, fill = FALSE, strip.white = FALSE, quiet = FALSE, blank.lines.skip = TRUE, multi.line = TRUE, comment.char = "", allowEscapes = FALSE, fileEncoding = "", encoding = "unknown", text)
部分参数的名称、取值及意义如表2.9所示.
表2.9 scan()函数中部分参数的名称、取值及意义
§2.4.2 读取Excel表格数据
已知数据(见表2.10),将表中的数据保存成Excel表格("educ_scores.xls"). 但R无法直接读Excel表格,需要将Excel表格转化成其他格式,然后才能被R软件读出.
表2.10 某学院学生数据
1. 转换成文本文件
第一种转化格式是将Excel表转换成“文本(制表符分隔)”文件,其保存过程如图2.12所示. 然后调用read.delim()函数读该文本文件,其命令为:
> read.delim("educ_scores.txt")
函数的返回值为数据框.
read.delim()函数的一般使用格式为:
read.delim(file, header = TRUE, sep = "\t", quote="\"", dec=".", fill = TRUE, comment.char="", ...)
部分参数的名称、取值及意义如表2.11所示.
表2.11 read.delim()函数中部分参数的名称、取值及意义
图2.12 将Excel表存为文本文件
2. 转换成CSV文件
第二种转化格式是将Excel表转换成“CSV(逗号分隔)”文件,其保存过程如图2.13所示. 然后调用read.csv()函数读该文本文件,其命令为:
图2.13 将Excel表存为CSV文件
> read.csv("educ_scores.csv")
函数的返回值为数据框.
read.csv()函数的一般使用格式为:
read.csv(file, header = TRUE, sep = ",", quote="\"", dec=".", fill = TRUE, comment.char="", ...)
参数的意义与read.delim()函数相同(见表2.11).
3. 直接读取Excel数据表
应用上述方法,可以说,已经解决了读取Excel表格数据的问题,但仔细想想,这个问题还是没有得到根本的解决. 因为在遇到大量的Excel表格数据时,每个表格都要做转换,这样既不经济,也不方便. 因此,根本解决此问题的方法就是直接读取Excel表格数据.
打算直接读取Excel表格,需要到CRAN镜像下载程序包,调用相关函数来读取数据,其过程如下。
(1)设定CRAN镜像. 其命令格式为“程序包->设定CRAN镜像...”(见图2.11),选择一个镜像.
(2)安装程序包. 其命令格式为“程序包->安装程序包...”,此时弹出程序包窗口,选择RODBC程序包,按“确定”按钮,计算机下载并自动更新.
上述两个步骤可由命令
> install.packages("RODBC")
完成.
(3)加载程序包. 其命令格式为“程序包->加载程序包...->RODBC”. 也可由命令
> library(RODBC)
完成.
(4)用odbcConnectExcel()函数完成ODBC库与Excel表格的连接,再用sqlTables()函数得到Excel表格信息. 其命令格式为:
> con <- odbcConnectExcel("educ_scores.xls") > tbls <- sqlTables(con)
(5)读取Excel表格中的数据. 这里有两种方式.
方式一
> sh1 <- sqlFetch(con, tbls$TABLE_NAME[1])
方式二
> qry <- paste("select * from [", tbls$TABLE_NAME[1], "]", sep="") > sh2 <- sqlQuery(con, qry); sh2
两种方法都可以读取Excel表格,且得到的sh1和sh2均为数据框.
(6)最后关闭连接.
> close(con)
4. 数据集的读取
统计计算中,有一些典型的数据案例,如Fisher Iris数据、二氧化碳数据、Anscombe数据等. 为便于大家使用,R提供了100多个这样的数据集(Datasets),可通过data()函数查看或加载这些数据集,如命令为:
> data()
列出在基本程序包(Base)中所有可利用的数据集. 如果要加载某个数据集,只需在括号中加入数据集的名称[7],如:
> data(infert)
如果想查看或加载其他程序包的数据集,其格式为:
data(package = "pkname") data(dataname, package = "pkname")
pkname为程序包的名称,dataname为数据集的名称. 例如,如果要显示cluster程序包中的数据集,其命令为:
> data(package = "cluster")
要加载cluster程序包中的agriculture数据集,其命令为:
> data(agriculture, package = "cluster")
查看或加载其他程序包数据集的方法还有另一组命令,其格式为:
library("pkname") ##加载程序包 data() ##查看数据集 data(dataname) ##加载数据集
§2.4.3 写数据文件
1. write函数
write()函数将数据写入纯文本文件,其使用格式为:
write(x, file = "data", ncolumns = if(is.character(x)) 1 else 5, append = FALSE)
参数的名称、取值及意义如表2.12所示.
表2.12 write()函数中参数的名称、取值及意义
例如:
> X <- matrix(1:12, ncol = 6); X [,1] [,2] [,3] [,4] [,5] [,6] [1,] 1 3 5 7 9 11 [2,] 2 4 6 8 10 12 > write(X, file = "Xdata.txt")
打开Xdata.txt文件,文件中的内容为:
1 2 3 4 5 6 7 8 9 10 11 12
这表明在写数据的过程中,是将数据按列写的,在默认值的情况下,每行5个数据.
2. write.table函数和write.csv函数
write.table()函数将数据写成表格形式的文本文件,write.csv()函数将数据写成CSV格式的Excel表格,其使用格式为:
write.table(x, file = "", append = FALSE, quote = TRUE, sep = " ", eol = "\n", na = "NA", dec = ".", row.names = TRUE, col.names = TRUE, qmethod = c("escape", "double"), fileEncoding = "") write.csv(...) write.csv2(...)
部分参数的名称、取值及意义如表2.13所示.
表2.13 write.table()等函数中部分参数的名称、取值及意义
例如:
> df <- data.frame( Name = c("Alice", "Becka", "James", "Jeffrey", "John"), Sex = c("F", "F", "M", "M", "M"), Age = c(13, 13, 12, 13, 12), Height = c(56.5, 65.3, 57.3, 62.5, 59.0), Weight = c(84.0, 98.0, 83.0, 84.0, 99.5) ) > write.table(df, file = "foo.txt") > write.csv(df, file = "foo.csv")