1. 首页
  2. 自学中心
  3. 软件
  4. R

数据帮:R对常用格式数据读入(txt\csv\excel)

原创:金小贝  QQ交流:675229288

        作为一个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数据读入
数据帮:R对常用格式数据读入(txt\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以空格为界分开为两个字段,改变了初始要求。

read.fwf( )函数还有一个较为灵活的使用方法,可灵活提取指定字段,依然是核心参数width控制,实现如下:
data_fwf2 <- read.fwf(‘data_fwf.txt’, width=c(-4,12,-20,3))     #只取IP、用户名

data_fwf2

            V1    V2
1 192.162.1.1   示例
2 192.162.1.2  示例2
3 192.162.1.3  用户3
条条大路通罗马,不一样的方法,相同的结果,各有优缺,建议选择一套自己习惯的数据读入方法即可。

附录:用于演示的数据,可复制到相对应的文件中使用

2013-05-01 其他 12000
2013-05-01 省份1 3000
2013-05-01 省份2 3002
2013-05-01 省份3 3000
2013-05-01 省份4 400
2013-05-01 省份5 50
2013-05-01 省份6 4000
2013-05-01 省份7 460
2013-05-01 省份8 400
2013-05-01 省份2 220
2013-05-01 身份10 400
2013-05-01 SSS 43
2013-05-01 省份12 400
2013-05-01 省份13 600
2013-05-01 省份10 6600
2013-05-01 省份11 1300
2013-05-02 省份19 10000
2013-05-02 省份1 3200
2013-05-02 省份2 300
2013-05-02 省份3 3800
2013-05-02 省份4 4000
2013-05-02 省份5 6000
2013-05-02 省份6 490
2013-05-02 省份7 4000
2013-05-02 省份8 3700
2013-05-02 省份9 200
2013-05-02 省份10 6200
2013-05-02 省份11 1000
2013-05-03 其他 120
2013-05-03 省份1 48000
2013-05-03 省份2 4100
2013-05-03 省份3 2200
2013-05-03 省份4 742000
2013-05-03 省份5 5500
2013-05-03 省份6 6230
2013-05-03 省份7 64600
2013-05-03 省份8 622000
2013-05-03 省份9 21600
2013-05-03 省份10 69000
2013-05-03 省份11 1200
2013-05-04 其他 1400
2013-05-04 省份1 5000
2013-05-04 省份2 50
2013-05-04 省份3 5200
2013-05-04 省份4 7600
2013-05-04 省份5 4800
2013-05-04 省份6 7900
2013-05-04 省份7 8700
2013-05-04 省份8 60
2013-05-04 省份9 20
2013-05-04 省份10 800
2013-05-04 省份11 1400
2013-05-05 其他 100
2013-05-05 省份1 64000
2013-05-05 省份2 600
2013-05-05 省份3 300
2013-05-05 省份4 800
2013-05-05 省份5 600
2013-05-05 省份6 800
2013-05-05 省份7 800
2013-05-05 省份8 700
2013-05-05 省份9 300
2013-05-05 省份10 8000
2013-05-05 省份11 100
2013-05-05 省份12 400
2013-05-05 省份13 40
2013-05-05 省份14 1600

原创文章,作者:金小贝,如若转载,请注明出处:http://www.17bigdata.com/%e6%95%b0%e6%8d%ae%e5%b8%ae%ef%bc%9ar%e5%af%b9%e5%b8%b8%e7%94%a8%e6%a0%bc%e5%bc%8f%e6%95%b0%e6%8d%ae%e8%af%bb%e5%85%a5%ef%bc%88txtcsvexcel%ef%bc%89/

联系我们

在线咨询:点击这里给我发消息

邮件:23683716@qq.com

跳至工具栏