【2.1】R读写数据
一、读数据
R在读取数据的时候针对不同的数据有不同的读取方法:
read.table, read.csv, for reading 表格数据
readLines 读取text的各行,类似perl读数据方式。
source 读取R命令文件(inverse of dump)
dget 读取R命令文件(inverse of dput)
load 导入保存保存的工作路径<!-- more -->unserialize for reading single R objects in binary form
scan( ):将数据读作一行向量形式。
read.delim("educ_scores.txt"):读入文本文件(制表符分隔)。
read.csv("educ_scores1.csv"):读入CSV(逗号分割)。
readBin( ):读入二进制数据。
readChar( ):读入字符型数据。
attach( ): 把数据框的变量链接到内存中.
1.1 read.table
read.table()
Reads a file in table format and creates a data frame from it, with cases corresponding to lines and variables to fields in the file.
根据数据行和列读成数据矩阵。
是读取数据中最广泛使用的
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")
file 文件的名字,或者是一个链接
header:逻辑参数。指定是否文件第一行为变量名。
na.strings:指定缺失文字。
skip:指定读数据跳过的行数。
nrows:指定数据读入最大的行数。
dec:指定小数点记号。
sep:指定数据分割字符。
row.names与col.names:赋予数据行名和列名。
colClasses 数据中每列的类型
comment.char 注释字符
stringsAsFactors字符变量是否变为因子
例如:下面的三个都可以
> read.table("qiuworld.com.txt",header=TRUE,sep="\t",quote="",comment.char="#")
> read.delim("qiuworld.com.txt",header=TRUE,sep="\t",quote="",comment.char="#")
> read.csv("qiuworld.com.txt",header=TRUE,sep="\t",quote="",comment.char="#")
如果只读取前5行,可以这样:
> read.delim("qiuworld.com.txt",comment.char="#",nrows=5)
读第3段开始的5段
> read.delim("qiuworld.com.txt",header=F,nrows=5,skip=3)
注释
默认情况下,read.table 用 # 作为注释标识字符。如果碰到该字符(除了在被引用的字符串内),该行中随后的内容将会被忽略。只含有空白和注释的行被当作空白行。
如果确认数据文件中没有注释内容,用 comment.char = "" 会比较安全 (也可能让速度比较快)。
read.table常见的问题:
1.1 编码问题
如果文件中包含非-ASCII字符字段,要确保以正确的编码方式读取。这是在UTF-8的本地系统里面读取Latin-1文件的一个主要问题。此时,可以如下处理
read.table(file(“file.dat”, encoding=“latin1”))
注意,这在任何可以呈现Latin-1名字的本地系统里面运行。
1.2 首行问题
我们建议你明确地设定 header 参数。按照惯例,首行只有对应列的字段而没有行标签对应的字段。因此,它会比余下的行少一个字段。(如果需要在 R 里面看到这一行,设置 header = TRUE。)如果要读取的文件里面有行标签的头字段(可能是空的),以下面的方式读取
read.table(“file.dat”, header = TRUE, row.names = 1)
列名字可以通过 col.names 显式地设定;显式设定的名字会替换首行里面的列名字(如果存在的话)。
1.3 分隔符问题
通常,打开文件看一下就可以确定文件所使用的字段分隔符,但对于空白分割的文件,可以选择默认的sep = "" (它能使用任何空白符作为分隔符,比如空格,制表符,换行符), sep = " " 或者 sep = “\t”。注意,分隔符的选择会影响输入的被引用的字符串。 如果你有含有空字段的制表符分割的文件,一定要使用 sep = “\t”。
1.4 引用
默认情况下,字符串可以被 " 或 ' 括起,并且两种情况下,引号内部的字符都作为字符串的一部分。有效的引用字符(可能没有)的设置由参数 quote 控制。对于sep = “\n”,默认值改为 quote = “"。 如果没有设定分隔字符,在被引号括起的字符串里面,引号需要用 C格式的逃逸方式逃逸,即在引号前面直接加反斜杠 \。 如果设定了分隔符,在被引号括起的字符串里面,按照电子表格的习惯,把引号重复两次以达到逃逸的效果。例如
‘One string isn'’t two’,“one more”
可以被下面的命令读取
read.table(“testfile”, sep = “,")
这在默认分隔符的文件里面不起作用。
1.5缺损值
默认情况下,文件是假定用 NA 表示缺损值,但是,这可以通过参数 na.strings 改变。参数 na.strings 是一个可以包括一个或多个缺损值得字符描述方式的向量。 数值列的空字段也被看作是缺损值。
在数值列,值 NaN,Inf 和 -Inf 都可以被接受的。
1.6 尾部空字段省略的行
从一个电子表格中导出的文件通常会把拖尾的空字段(包括?堑姆指舴? 忽略掉。为了读取这样的文件,必须设置参数 fill = TRUE。
1.7 字符字段中的空白
如果设定了分隔符,字符字段起始和收尾处的空白会作为字段一部分看待的。为了去掉这些空白,可以使用参数 strip.white = TRUE。
1.8 空白行
默认情况下,read.table 忽略空白行。这可以通过设置 blank.lines.skip = FALSE 来改变。但这个参数只有在和 fill = TRUE 共同使用时才有效。这时,可能是用空白行表明规则数据中的缺损样本。
1.9 变量的类型
除非你采取特别的行动,read.table 将会为数据框的每个变量选择一个合适的类型。如果字段没有缺损以及不能直接转换,它会按 logical, integer, numeric 和 complex 的顺序依次判断字段类型。如果所有这些类型都失败了,变量会转变成因子。
参数 colClasses 和 as.is 提供了很大的控制权。 as.is 会 抑制字符向量转换成因子(仅仅这个功能)。 colClasses运行为输入中的每个列设置需要的类型。
注意,colClasses 和 as.is 对每 列专用,而不是每个变量。因此,它对行标签列也同样适用(如果有的话)。
1.10 注释
默认情况下,read.table 用 # 作为注释标识字符。如果碰到该字符(除了在被引用的字符串内),该行中随后的内容将会被忽略。只含有空白和注释的行被当作空白行。
如果确认数据文件中没有注释内容,用 comment.char = "” 会比较安全 (也可能让速度比较快)。
1.11 逃逸
许多操作系统有在文本文件中用反斜杠作为逃逸标识字符的习惯,但是Windows系统是个例外(在路径名中使用反斜杠)。在 R 里面,用户可以自行设定这种习惯是否用于数据文件。
read.table 和 scan 都有一个逻辑参数 allowEscapes。从 R 2.2.0 开始,该参数默认为否,而且反斜杠是唯一被解释为逃逸引用符的字符(在前面描述的环境中)。如果该参数设为是,以C形式的逃逸规则解释,也就是控制符如 \a, \b, \f, \n, \r, \t, \v,八进制和十六进制如 \040 和 \0x2A 一样描述。任何其它逃逸字符都看着是自己,包括反斜杠。
读取粘贴板中的数据
先将数据ctrl +c 复制,然后
aa <- read.table(file='clipboard',header = FALSE)
as.data.frame(table(aa)) #返回矩阵,第一列levels 第二列频数freq
1.2 read.csv
arc<-read.csv("/sam/abd/arc_classified.csv",header=TRUE,sep="\t",quote="",comment.char="#",as.is = T);
arc<-read.csv("/sam/abd/arc_classified.csv",header=TRUE,sep="\t",quote="",comment.char="#")
<strong>read.csv的一个特性是会自动地将非数值类型的数据视为因子(factor),即分类变量</strong>。但在某些情况下,也有可能确实需要字符串,而不是因子。把<strong>as.is参数设为TRUE即可,此时R就不会将分数值数据视为因子。</strong>
comment.char="#" 忽略#的行,comment.char=""可以禁用。str(arc$family.n) #查看数据类型。
方法1读入的百分数为chr,方法2读入的百分数为factor
1.3 scan
问题是,以上的文件都是格式化的表格文件。如果文件并非表格式文件,而是一些的字符或者数字,并且每行长度不同呢?我们可以使用scan来输入。
scan()
Read data into a vector or list from the console or file.
读成向量或列表
> scan("qiuworld.com.txt",what=character(),sep="\t",fill=F,comment.char="#")
Read 27 items
[1] "ArrayDataFile" "SourceName" "FactorValue" "GSM286765.CEL" "t_24h_rep1" "treated_24h"
[7] "GSM286759.CEL" "t_12h_rep1" "treated_12h" "GSM286763.CEL" "c_24h_rep2" "control_24h"
[13] "GSM286760.CEL" "t_12h_rep2" "treated_12h" "GSM286757.CEL" "c_12h_rep2" "control_12h"
[19] "GSM286766.CEL" "t_24h_rep2" "treated_24h" "GSM286756.CEL" "c_12h_rep1" "control_12h"
[25] "GSM286762.CEL" "c_24h_rep1" "control_24h"
>scan("qiuworld.com.txt",what=list(ArrayDataFile=character(),SourceName=character(),FactorValue=character()),skip=2,nlines=5,comment.char="#")
Read 5 records
$ArrayDataFile
[1] "GSM286765.CEL" "GSM286759.CEL" "GSM286763.CEL" "GSM286760.CEL" "GSM286757.CEL"
$SourceName
[1] "t_24h_rep1" "t_12h_rep1" "c_24h_rep2" "t_12h_rep2" "c_12h_rep2"
$FactorValue
[1] "treated_24h" "treated_12h" "control_24h" "treated_12h" "control_12h"
1.4 read.DNAStringSet
读入sequence文件(比如fasta, fastq, BAM, gff, bed, 或者 wig)
> library("Biostrings")
> read.DNAStringSet("qiuworld.com.fasta")
一些小点的数据集,可以省略上面的一些参数
data <- read.table("foo.txt")
R会自动的进行:
跳过以#开始的行;
计算多少行,以及需要多少内存;
每一列的变量类型;
如果通过参数告诉R可以让R运行的更快一些
read.csv跟read.table一样,除了默认的分隔符是逗号
1.5 readLines
readLines功能可以用来简单的读取文本文件的行,然后通过字符向量来存储他们
> con <- gzfile("words.gz")
> x <- readLines(con, 10)
> x
[1] "1080" "10-point" "10th" "11-point"
[5] "12-point" "16-point" "18-point" "1st"
[9] "2" "20-point"
readLines也可以用来读取网页的每一行
## This might take time
con <- url("http://www.jhsph.edu", "r")
x <- readLines(con)
> head(x)
[1] ""
[2] ""
[3] ""
[4] ""
[5] "\t
1.6 file
数据通过连接接口被读取,链接可以指向文件也可以是其他的东西。
file, opens a connection to a file
gzfile, opens a connection to a file compressed with gzip
bzfile, opens a connection to a file compressed with bzip2
url, opens a connection to a webpage
>** str(file)**
function (description = "", open = "", blocking = TRUE,
encoding = getOption("encoding"))
description是文件的名字
open预示文件的类型
“r” read only
“w” writing (and initializing a new file)
“a” appending
“rb”, “wb”, “ab” reading, writing, or appending in binary mode (Windows)
一般情况下,connections是一个非常强大的工具,可以让你找到文件,并连接到上面去,但实际中,我们并没有必要通过它来,可以直接读取数据。
con <- file("foo.txt", "r") #通过con先连接数据
data <- read.csv(con)
close(con)
也可以这样
data <- read.csv("foo.txt")
1.7 dput与dget
用dput来deparsing the R object,dget来读取它
> y <- data.frame(a = 1, b = "a")
> dput(y)
structure(list(a = 1,
b = structure(1L, .Label = "a",
class = "factor")),
.Names = c("a", "b"), row.names = c(NA, -1L),
class = "data.frame")
> dput(y, file = "y.R") #给文件命令了,否则就像上面的在终端显示
> new.y <- dget("y.R") #用dget来读取
> new.y
a b
1 1 a
1.8 dump与source
同的对象可以用dump来deparsed,然后用source来读取。
> x <- "foo"
> y <- data.frame(a = 1, b = "a")
> dump(c("x", "y"), file = "data.R")
> rm(x, y)
> source("data.R")
> y
a b
1 1 a
> x
[1] "foo"
注意:
对于很大的数据来说,下面的一些提示可以对于有一些帮助:
- 认真读一下 read.table的帮助说明
- 粗略的计算一下需要多少内存来存储你的数据,如果数据大于你计算机的RAM,那你可以立马停止工作了。
内存是多大?
那些应用正在使用
其他的用户有没有在使用?
你的系统是啥子? >st r(.Platform)
32位还是64位捏? >version
计算内存:
I have a data frame with 1,500,000 rows and 120 columns, all of which are numeric
data. Roughly, how much memory is required to store this data frame?
1, 500, 000 * 120 *8 bytes/numeric = 1440000000 bytes
= 1440000000/220 bytes/MB
= 1, 373.29 MB
= 1.34 GB
3.如果没有注释行,设置comment.char = "”
4,使用colClasses参数,而不是使用默认值可以让 ’read.table’运行的更快,一般速度提升一倍哦.如果使用这个参数的话,你就必须知道每列的类别。如果所有的列都是数字类型,你可以设置colClasses = “numeric”。你可以用这个方法知道每一列是什么类型:
initial <- read.table("datatable.txt", nrows = 100)
classes <- sapply(initial, class)
tabAll <- read.table("datatable.txt",colClasses = classes)
5,设置nrows参数,这个参数不能使R变快,但是能节约内存,你可以使用 Unix工具wc来计算这个文件的行数
二 、写数据
write.table
writeLines
dump
dput
save
serialize
2.1 write.table
write.table(df, file="file_name.txt", quote=FALSE, sep = " ", row.names=FALSE)
以数据框为例:
df 是数据框对象
file 文件名(没有路径的话直接保存在当前工作目录下,getwd()查看工作目录)
quote 是否在数据上添加引号,(默认是TRUE,添加引号的)
sep 是字段分隔符,默认是空格(“\t”是制表符号,如果需要复制粘贴到表格中,则用制表符)
row.names 是否显示记录名称,没有特别的名称的话,是 1,2,3,4
完整用法
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 = "")
append = TRUE, 如果文件夹中已有相同的名字,则自动扩展, append = FALSE,如果文件夹中已有相同的名字,则覆盖同名的文件, 总之,在使用处理大数据之前,你需要知道你系统的一些信息
2.2 writeLines
读取字符向量然后每个元素一行的来写入文本文件中
注:
文本格式
dumping和dputing非常有用,因为结果文本格式是可编辑的,同时如果崩溃后也是可能找回来的。 跟table或csv不一样,dump和dput保存了宏数据(牺牲了一些可读性),这样其他的用户就没有必要重复的制定数据了
文本格式比只能在文本文件中跟踪改变的控制程序(例如subversion or git)更方便一些
文本格式可以长久保存,如果某个地方有问题,也方便修改
文本格式Unix philosophy紧密相连
但是呢文本格式不是太节约空间。
R从使用分界符的文本(delimited text)读取数据到数据框的命令为read.table()。关于此文本的格式,有以下要求: 行的分界符为换行/回车,列的分界符为空格或制表符(TAB)。 特别注意,R把任意多个连续的空格或制表符只算作一个。
由于R把连续空格或制表符只算作一个,如果数据表中有空缺的单元格,将会导致R读入时列发生错位。 如果数据表中有空缺的单元格,一定要用NA来表示缺失的数据,否则将会导致读入数据错位。 一般来说第一行用来存放变量名。如果第一行不是变量名,R用“V1, V2, …”来命名变量。 为了以后方便地跟踪数据,应当设置ID列。一般来说第一列用来存放ID。 如果变量名比数据列少一个,R将假定第一列为ID列。
三、删除数据
file.remove("gc.pdf")
四、Excel的处理
install.packages("readxl")
library(readxl)
samples = read_excel('v:\\data/We/reference/20170330样本信息.xlsx','analysis')
参考资料
- Roger D. Peng的《Computing for Data Analysis》
- 糗世界 http://pgfe.umassmed.edu/ou/archives/2509
- http://www.cnblogs.com/xianghang123/archive/2012/06/06/2538274.html
- http://www.cnblogs.com/yupeter007/p/5421702.html
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn