数据整理

整理和管理数据

052009

如果你想掩盖数据,那么就把它们离散化吧!

不知道为什么这么多人钟爱于将连续数据离散化,例如明明有年龄数据,在分析的时候非要分成老幼青壮这样的分类变量;明明有原始的计数数据,非要搞成“0-5、6-10、……”这样的频数表。大概是数据得来不花钱吧,这样毁灭信息一点都不心疼。

某年我在某医学统计会议上专门强调了这个愚蠢的问题,结果后面还有某小师妹没理解我的意思,把我批驳了一番,依然支持离散化,我无语,只能摇摇头叹口气。去年useR! 2008会议上,Frank Harrell也提到了这个问题,他也想不通,为什么人们喜欢离散化。

如果你问一位lady:请问姑娘芳龄多少哇?姑娘回答:臣妾属于0~100岁这一组的。我想,此时这些人该能理解离散化的毛病所在了吧。

222008

有人对数据的导入/导出产生疑问,比如SPSS怎样导进LISREL,或是SAS怎样导进Stata,或是Excel怎样导进R,等等。其实一般情况下这种问题并不是什么大问题,我们总是被软件蒙蔽,猜不透数据文件背后究竟是什么,或者根本没有想过文件里面究竟是什么。我对计算机文件的机制了解并不多,我只知道两种基本的格式:ASCII格式(或纯文本格式)以及二进制格式。后者是经过某种规则编码了的,所以用纯文本编辑器打开一般看不到内容,而前者就简单多了,用任何纯文本编辑器(如记事本)都可以打开看。

纯文本格式是几乎任何软件都支持读写的,因此它可以成为软件之间互相“沟通”的桥梁。比如Excel可以另存为CSV文件,然后由R用read.csv()读进来或者由SPSS的Read Text Data导进去,等等。所以一般情况下通过纯文本文件行事就足够了。

统计数据的形式一般都是二维表格,行为观测,列为变量;纯文本数据中当然要想办法将行列用一定的标志区分开来。对于行,当然就是换行符(例如回车),这没什么好说的,用编辑器打开看到就是一行一行的;对于列,则稍有不同,这就涉及到分隔符(separator / delimiter)的问题了,它们的作用就像是Excel或者其它表格软件中的网格线一样,将一列一列分隔开来,每一列对应一个变量,分隔符可以是任何字符,但常见的一般是逗号(,)或者制表符(\t,Tab)。所谓CSV文件,也就是以逗号为分隔符的纯文本文件,我们可以将Excel数据存为CSV格式,然后用记事本打开看看就明白了。Windows下CSV文件(*.csv)的图标一般是Excel的图标,其实这是很具有误导性的,CSV与Excel毫无关系,只是纯文本文件的一种而已。

这是关于数据的很基础的知识,但我发现很多人并不明白。怪哉。

纯文本文件之外的统计数据我通常推荐采用专门的数据库作为存储工具(尤其是支持SQL的数据库),而不是Excel或SPSS等软件,用数据库捣腾数据一方面比那些看起来易用的Excel或SPSS更高效,另一方面也比较安全。前面我刚刚谈过这个问题

从今以后,关于数据导入/导出的邮件我也将不再回复。

142007

不知道这样一个程序要跑多久:文件下载链接

setwd("e:/download/")
files = list.files("training_set", full.names = T)
writeLines("movieID,customerID,Rating,ratingDate,movieReleaseDate",
   "training_set.csv")
for (i in 1:17770) {
   x = read.csv(files[i], F, skip = 1, as.is = F, stringsAsFactors = F)
   x = cbind(i, x, read.csv("movie_titles.txt", F, nrows = 1,
       skip = i - 1, as.is = F, stringsAsFactors = F)[1, 2])
   write.table(x, file = "training_set.csv", append = T, sep = ",",
       row.names = F, col.names = F, quote = F)
}

当我没加入第7~8行的read.csv()那一句时,程序在WinXP+奔四3.0GHz+512M内存下跑了47分钟把一个2G多的CSV数据文件写完了。不过等我用SQL语句去读其中一列时,发现内存终于不够用了。

Netflix的奖金是1,000,000$,呃,这么大一堆钱,做做梦吧。莫非这个奖还要比拼各家的计算机配置?国内啥时候能有这样的悬赏啊?

122007

9号通宵大战,总算大致赶完了一篇报告。这个通宵让我创下了42小时不睡觉的记录,其惨烈程度可想而知。这篇 报告的主题是针对人口抽样调查数据进行分析,得出地区人口素质的一些描述性结论。其实我的相当大一部分时间都花在了处理数据上面,因为数据比较庞大,一共 有260万行、90个变量,数据文件大小在FoxPro存储格式下为424M,首先我要想办法将 FoxPro数据转化为一般常见的数据库格式,因此将之导出为dBase IV(*.dbf),这样SPSS就可以读了(当然也可以用R的RODBC包读), 从dBase IV转为SPSS格式(*.sav)之后文件大小变为约1.5G,但很容易就能找出减小数据文件大小的办法:将以文本形式(String)表示的数字转化 为数值型(Numeric)即可(其实这份数据中的大部分数值都是用文本形式保存的,除非以零开头,都可以直接转换为数值形式)——我并不了解真正的 SPSS存储形式,但我猜测对于字符数据,至少要比数值数据多两个引号吧。初步整理之后,文件大小能缩减到400多M,当然我是不会直接用SPSS来作分 析的,因为速度太慢,一个变量的频数统计就要花半分钟时间,我可没那么多时间和耐心去等。最终我采用的办法是将数据存为纯文本格式,具体来说是逗号分隔符 数据(*.csv),然后开始用R来作分析。到这里,数据的预处理仍然没有结束,我为了让分析做得更快,又采取了一个策略:将每一列变量都单独存为一个数 据文件。要达到这样的目的,当然要首先把每一列变量提取出来,那么怎样依次提取变量呢?方法很简单,用SQL的select语句即可。文本文件当然也可以 当作数据库来处理,因为Windows一般会有文本文件的ODBC Driver,利用R的RODBC包结合SQL的select语句,变量就可以顺利被选择出来了。

WWW.YIHUI.NAME XIE@YIHUI.NAME © 2007 - 2010 by Yihui Xie