作为一个R新手,安装完R软件,IDE也选定安装好了之后,最跃跃欲试的是什么?反正我是读入数据!当时是这样,在RStudio里打印出“Hello World!”之后,马上动手读入我本地的excel数据,准备开启自己的大R之旅,结果令人大跌眼镜,鼓捣了半天也没把excel里的数据读入到R的内存中。简直步步是坑,动手就错误提示,关键还看不懂,心想这么简单点事都搞不定,把电脑砸了的心都有。现在看来有些小白的问题我还原一下,然后好好记录,希望遇到此类问题的朋友们可以得以受益。
本文中常用的数据格式指txt、csv、excel(一般指excel2007及以后版本的xlsx文件),涉及到的包涉及到R自带的系统包,也包括需要单独再加载的用户包,具体崩溃的过程如正文。所有示例文件都存放在D盘R文件夹中,如data.txt,为R的工作目录,所有测试数据均为自编的,内容一致,具体数据见本文最后附录,只是文件格式不同,测试过程中读者可自行生成文件,文件名为data.txt、data.csv、data.xls、data.xlsx。
一、txt数据读入
函数read.table()来自R系统包utils,可以使用命令?read.table先了解详细内容,后面会做详细解释。
?read.table #帮助用?或者help()可以查询帮助
开始
data_txt <- read.table(data.txt)
Error in read.table(data.txt) : object ‘data.txt’ not found
#错误1:R无法找到对象。太心急了没写路径R不知道去哪里找文件
data_txt <- read.table(D:\R\data.txt)
Error: unexpected input in “data_txt <- read.table(D:\”
#错误2:不期望的输入出现。补充了路径也不行,原来R很多时候输入需要双引号括起 “XXX”,其实单引号也行 ‘XXX’,当然引号需要半角输入
data_txt <- read.table(‘D:\R\data.txt’)
Error: ‘\R’ is an unrecognized escape in character string starting “‘D:\R”
#错误3:不认识的输入\R。加了引号反而不认识了,\被当做转移字符处理了,所以R需要反其道而行之,路径要用左斜杠/
data_txt <- read.table(‘D:/R/data.txt’)
#没任何提示?难道搞定了?用head函数看一下
head(data_txt)
V1 V2 V3
1 2013-05-01 鍏朵粬 12000
2 2013-05-01 鐪佷唤1 3000
3 2013-05-01 鐪佷唤2 3002
4 2013-05-01 鐪佷唤3 3000
5 2013-05-01 鐪佷唤4 400
6 2013-05-01 鐪佷唤5 50
是的,数据读入成功!到目前为止成功将本地txt数据导入到R内存,赋值给data_txt对象。但是看数据有些傻眼,乱码问题后面再说。通常还有另外2种写法可以达到相同结果,如下:
data_txt1 <- read.table(‘D:\\R\\data.txt’) #转移字符加\表示路径
setwd(‘D:/R’) #设置R的工作路径到D盘R文件夹,getwd()为获得当前R的工作路径
data_txt2 <- read.table(‘data.txt’) #设置好路径后可简单地直接读取文件名+后缀
这时候data_txt、data_txt1、data_txt2三个对象均保存了相同的数据。
解读:数据导入需要文件名+后缀,需要引号而且是半角格式(单引号双引号均可),文件路径有三种方法
1、全路径:使用右斜杠,需要2个\\,如data_txt1
2、全路径:使用左斜杠/,一个即可,如data_txt
3、(推荐)设置全局工作路径setwd(),然后直接读取文件名,如data_txt2
常见其他问题:
1、乱码(如上鍏朵粬):在读取汉字的时候出现乱码,解决办法:设置参数encoding=’UTF-8′
data_txt2 <- read.table(‘data.txt’, encoding=’UTF-8′)
2、某行的元素个数与列数对应不上,错误提示
Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec, :
line 12 did not have 3 elements
一般是在数据库导出数据的时候可能某行存在格式不一致,比如多一个tab制表符,或者其他一些莫名原因(个人曾经遇到过格式完全没有问题,但就是提示错误,最后发现是这个文件里的某个字就会出现提示,至今不得解),解决办法:设置参数fill=TRUE
data_txt2 <- read.table(‘data1.txt’, encoding=’UTF-8′, fill=TRUE)
3、读入的数据格式发生变化,强制转换为因子格式,解决办法:设置参数as.is可单独保留原数据格式不做转换,如as.is=c(1,2,3)指1、2、3列不做因子转换。
read.table()函数
read.table(file, header = FALSE, sep = “”, quote = “\”‘”,
dec = “.”, numerals = c(“allow.loss”, “warn.loss”, “no.loss”),
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, skipNul = FALSE)
常用参数说明:
参数1:file,需要导入的文件,包括文件的路径、名称、后缀
参数2:header,是否有变量名,默认为FALSE,设置为T则把第一行做为变量名
参数3:sep,数据读取时的分隔符,默认为空格或制表符
参数4:encoding,防止出现中文乱码错误,可设置encoding=’UTF-8’
参数5:col.names,指定列名,col.names=c(‘列名1′,’列名2′,’列名3’);row.names为指定行名,一般用不着
参数6:as.is,是否保存原始字符型数据格式,默认为FALSE即全部转化为因子格式,设置为T则全部保留原数据格式,通过as.is=c(1,2)可单独设置某列不做转化
参数7:na.strings,缺失值转化为NA
参数8:skip,略过不读取前n行数据
参数9:blank.lines.skip,为T则忽略空白行,默认为TRUE
二、csv数据读入
走过了上面各种坑以及对read.table()函数的了解,之后相对容易,此处讲两种csv数据导入方法。
方法一:read.table()函数
data_csv <- read.table(‘data.csv’)
head(data_csv)
V1
1 2013/5/1,其他,12000
2 2013/5/1,省份1,3000
3 2013/5/1,省份2,3002
4 2013/5/1,省份3,3000
5 2013/5/1,省份4,400
6 2013/5/1,省份5,50
#直接read.table(),发现数据存在了一列,需要设置sep参数
data_csv <- read.table(‘data.csv’, sep=’,’, skip=2)
V1 V2 V3
1 2013/5/1 省份2 3002
2 2013/5/1 省份3 3000
3 2013/5/1 省份4 400
4 2013/5/1 省份5 50
5 2013/5/1 省份6 4000
6 2013/5/1 省份7 460
#顺利读入数据,并且没有乱码
解读:read.table()读入csv文件比较友好,无需顾忌中文乱码的问题,但是数据存储是以逗号分隔,所以注意sep参数设置sep=’,’ ,其他参数依然有效,如想跳过2行读入设置skip=2
方法二:read.csv()函数
其实read.csv()函数是专门为csv文件而生的基于read.table的一个封装,参数都可通用,不同之处在于sep默认为逗号而无需单独设置了,header默认为TRUE,知道这2点就OK了。
data_csv1 <- read.csv(‘data.csv’)
head(data_csv1)
X2013.5.1 其他 X12000
1 2013/5/1 省份1 3000
2 2013/5/1 省份2 3002
3 2013/5/1 省份3 3000
4 2013/5/1 省份4 400
5 2013/5/1 省份5 50
6 2013/5/1 省份6 4000
#默认header为T,所以第一行作为变量名了
data_csv1 <- read.csv(‘data.csv’, header=F, col.names=c(‘日期’,’省份’,’数据’))
head(data_csv1)
日期 省份 数据
1 2013/5/1 其他 12000
2 2013/5/1 省份1 3000
3 2013/5/1 省份2 3002
4 2013/5/1 省份3 3000
5 2013/5/1 省份4 400
6 2013/5/1 省份5 50
#顺利读入数据,并且设置了列名称
解读:read.csv()可以很方便的读入csv文件,推荐!需要注意header默认为T,这与read.table正好相反。在使用函数的时候发现还有一个read.csv2,看具体参数发现默认分隔符号为冒号sep = “;” ,平时没用到过,可能有些系统或地区或版本的csv是以冒号分隔,供了解。
三、excel数据读入
为什么read.xlsx()不存在?
对于最常用的excel文件提供三种解决方法:
方法一:将excel文件另存为csv格式,再通过read.csv导入即可,这个方法虽然多一次转换,但是行之有效,个人推荐这个方法,具体不在赘述。
解读:再次强调推荐使用此方法
方法二:利用RODBC包,函数odbcConnectExcel2007与sqlFetch结合
library(RODBC) #加载RODBC包
connect_channel <- odbcConnectExcel2007(‘data.xlsx’) #建立连接通道
sqlTables(connect_channel) #查看data.xlsx文件中有哪些表
data_excel <- sqlFetch(connect_channel,’省份数据’) #导入excel中指定sheet的数据
close(connect_channel) #关闭连接通道
head(data_excel)
2013/5/1 其他 12000
1 2013-05-01 省份1 3000
2 2013-05-01 省份2 3002
3 2013-05-01 省份3 3000
4 2013-05-01 省份4 400
5 2013-05-01 省份5 50
6 2013-05-01 省份6 4000
解读:有3点需要重点解释
1、完整流程是:首先要加载RODBC包(library),然后建立连接通道(odbcConnectExcel2007),之后提取相对应数据(sqlFetch),最后要关闭通道(close)。提取数据时需要知道sheet的名称,可通过sqlTables查询信息。
2、观察以上结果发现第一行数据做为列标题了,如何破?这里可以很负责任的告诉你:无法通过设置解决。因为sqlFetch函数在设计时将读取到的sheet里的第一行内容做为列的一个特征处理而非普通单元格,仔细研究会发现sqlFetch函数的colnames参数此时默认为FALSE,已经设置没有列名称了,如果修改为TRUE,会发现上面数据的标题( 2013/5/1 其他 12000)消失了,上面结果中行号为1的行作为标题了。那有解决办法吗?答案是有的,直接在excel中先添加上列名即可。
3、建立连接通道时用的函数是odbcConnectExcel2007,主要针对xlsx格式,如果要导入excel2007版本以前的xls格式需要使用odbcConnectExcel函数,其需要切换到32位系统环境中运行,参考Tools→Global Options→R version:Change→关闭/重启
方法三:使用xlsx包,read.xlsx()可以有
install.packages(‘xlsx’) #安装,可能出现很多问题
library(xlsx)
data_excel1 <- read.xlsx(‘data.xlsx’, sheetIndex = 1) #原数据文件也可以是xls文件,sheetIndex参数代表工作表顺序
head(data_excel1) #顺利导入,但是出现乱码
data_excel1 <- read.xlsx(‘data.xlsx’, sheetName = ‘省份数据’) #sheetName参数代表工作表名称,此处报错,不支持中文
data_excel1 <- read.xlsx(‘data.xlsx’,
sheetName = ‘province_data’,
encoding = ‘UTF-8’) #sheetName调整后可执行,乱码通过encoding参数控制,header默认为T
head(data_excel1)
日期 省份 数据
1 2013-05-01 其他 12000
2 2013-05-01 省份1 3000
3 2013-05-01 省份2 3002
4 2013-05-01 省份3 3000
5 2013-05-01 省份4 400
6 2013-05-01 省份5 50
解读:read.xlsx()函数优点之一在于可方便的对各版本excel文件进行统一读取(xlsx、xls均可),无需考虑系统和软件的位数,一站式完美解决。优点之二是对工作表的选择既可以通过表顺序(sheetIndex),也可以通过表名称(sheetName),选择方法多样。优点之三是直接生成数据框,并且保留了原始数据格式,方便后续处理。
不足之一是索引表名称不支持中文,此时只能通过sheetIndex参数完成工作表的选择。不足之二是xlsx包的安装比较麻烦,会自动安装xlsxjars包和rJava包,rJava包要求java环境同样匹配64位或者32位,根据不同电脑配置可能出现不一样的情况。
补充:read.xlsx2( )函数更加智能,自动处理乱码问题,对原始数据格式也自动转换为因子格式,比如原本日期格式的也自动转变为因子,根据个人喜好使用。
data_excel3 <- read.xlsx2(‘data.xlsx’, sheetIndex = 1)
head(data_excel3)
日期 省份 数据
1 41395 其他 12000
2 41395 省份1 3000
3 41395 省份2 3002
4 41395 省份3 3000
5 41395 省份4 400
6 41395 省份5 50
excel文件读入常用方法介绍完毕,重要的事情说三遍,推荐方法一:另存为csv格式,然后用read.csv()函数。
四、简单介绍:read.fwf( )函数
fixed width file固定宽度文件,主要应用场景是固定宽度数据的读入,特别适合网站日志数据的处理,使用参数如下:
read.fwf(file, widths, header = FALSE, sep = “\t”,
skip = 0, row.names, col.names, n = -1,
buffersize = 2000, fileEncoding = “”, …)
它与read.table( )函数在同一个系统包utils里,参数很多都是通用,widths参数是独有的,即需要读入的字段宽度,一般为向量。
假设D:/R里data_fwf.txt文件,内容包括用户ID、用户IP、注册时间、用户名,现在需要每列单独存放4个字段,原始数据如下(数据为示例仅做展示使用):
123 192.162.1.1 2016-01-05 12:12:12 示例
456 192.162.1.2 2016-01-06 03:00:00 示例2
789 192.162.1.3 2016-01-07 20:00:03 用户3
data_fwf <- read.fwf(‘data_fwf.txt’, width=c(4,12,20,3)) #分为4个字段,取数宽度分别为4,12,20,3
names(data_fwf) <- c(‘ID’,’IP’,’注册时间’,’用户名’)
data_fwf
ID IP 注册时间 用户名
1 123 192.162.1.1 2016-01-05 12:12:12 示例
2 456 192.162.1.2 2016-01-06 03:00:00 示例2
3 789 192.162.1.3 2016-01-07 20:00:03 用户3
解读:read.fwf( )函数应用较窄,特定应用场景使用,主要依赖width参数控制,需要注意的是空格也算一个宽度需要统一计算在同一字段内,读入后的数据会自动删除前后多余的空格。以上如果用read.table(‘data_fwf.txt’)则会默认将长日期格式的2016-01-05 12:12:12以空格为界分开为两个字段,改变了初始要求。