也许我们都经历过类似的问题,当我们使用软件比如R将一个gene list保存在一个csv文件之后交给别人编辑,再传回来,应该显示为SEPT2的基因被显示为一个数字。当我们使用Excel打开之后,会发现它变成了2-SEP这样的时间。原来,使用Excel将文件编辑过之后,会自动地将类似SEPT3这种基因名识别成日期,再保存的时候,就改变了它的值。
这是一个令人苦恼的问题。甚至NCBI的数据中也曾经出现这样的问题。
下图是原文章中可能会被EXCEL错误识别的所有的字符组合,它们很有可能本来是一个基因名。
为此,文章作者给出了一个脚本来对文件中可能会有的这种错误进行扫描。代码如下:
#! /bin/csh # written by b zeeberg 11/18/02 foreach arg ($*) echo $arg #The following line is supposed to be split in two for some arcane reason in sed tr "\r" "\n" < $arg | sed '1,$s/\^M/\\ /g' | gawk '(/[0-9]\-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC|Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/ || /[0-9]\.[0-9][0-9]E\+[[0-9][0-9]/) {print NR,$0}' end |
那么,这个问题在R当中是怎么解决的呢?如果你想保存为CSV文件,但是让别人使用EXCEL打开能够正常显示,那你可以使用下面的函数来保存和读取文件:
write.csv3 <- function(x, ...){ x <- gsub("^((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\\d+)$", "=\"\\1\"",x, ignore.case=T) write.csv(x, ...) } read.csv3 <- function(...){ x <- read.csv(...) for(i in 1:ncol(x)) x[,i] <- gsub("^=\"((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\\d+)\"$", "\\1", x[,i]) x } |
下面我们可以试验一下这两个函数。
> x <- matrix(c("JAN1","FEB2","MAR3","APR4","MAY5","JUN6","JUL7","AUG8","SEP9","OCT1","NOV1","DEC2"), + nrow=4) > x [,1] [,2] [,3] [1,] "JAN1" "MAY5" "SEP9" [2,] "FEB2" "JUN6" "OCT1" [3,] "MAR3" "JUL7" "NOV1" [4,] "APR4" "AUG8" "DEC2" > write.csv(x, "x.csv", row.names=F) |
write.csv3(x, "y.csv", row.names=F) |
读取文件
> y <- read.csv("x.csv") > y V1 V2 V3 1 JAN1 MAY5 SEP9 2 FEB2 JUN6 OCT1 3 MAR3 JUL7 NOV1 4 APR4 AUG8 DEC2 > z <- read.csv3("y.csv") > z V1 V2 V3 1 JAN1 MAY5 SEP9 2 FEB2 JUN6 OCT1 3 MAR3 JUL7 NOV1 4 APR4 AUG8 DEC2 > all(y==z) [1] TRUE |
但是这样操作有一个不妥,那就是如果你拿到一个文件,你并不知道它之前是如何保存的。为了保险,你在读取时都需要使用read.csv3来读取。但是别人并不一定会遵守这一规则。
在R中,有一个根本的办法,就是使用WriteXLS来写成XLS文件。这样的话,就不会出现上面的问题了。但是文件就不再是可读性强的文本文件了。
> library(WriteXLS) > WriteXLS("x", "x.xls") > library(gdata) > m <- read.xls("x.xls") > m V1 V2 V3 1 JAN1 MAY5 SEP9 2 FEB2 JUN6 OCT1 3 MAR3 JUL7 NOV1 4 APR4 AUG8 DEC2 > all(x==m) [1] TRUE |
用MS Excel打开基因列表文件时,不用直接打开,而是先新建一个空sheet,在‘Data’中选’External Data’,弹出的对话框里,将基因对应的列相应的格式先改为’text’即可解决该问题。