Stata

R 的 Vectorization

最先习惯的用的计量软件是 stata,然后是 vba for excel, 然后是 R,大概因为是这个学习路径,导致了在 R 中的一些不良习惯。 stata 的指令很多都是直接针对 vector 的,譬如下面的 panel data:

ID Year X Y
CHN 1990 45 36
CHN 1991 23 62
CHN 1992 55 90
JPN 1990 79 56
JPN 1991 60 72
JPN 1992 78 100

如果需要只需 CHN 的数据,在 stata 里只要:

keep if ID==”CHN”

就可以了。而 VBA 中因为 excel 表格的直观,一般是用 for  或者 do loop:

Sub chn()

n = Range("A50000").End(xlUp).Row
for i = n to 2 Step -1
if Cells(i,"A")!="CHN" then Cells(i,"A").entiredRow.delete
end if
next i

End Sub

因为 R 中的 if statement 不能直接针对 vector, 所以就习惯像 VBA 一样用 loop 来整理数据,但是因为 excel 中最大的数据量不过 6万五千多行 256 列,数据量并不大,所以用 loop 虽然慢,但是因为数据量的限制,还算能忍受,但是在 R 中,如果有上十万的 observations,再用 loop 就极其的痛苦了,虽然R中的loop 的效率要比 VBA 高(尽管不如 S),虽然刚换了 Duo Quad 的 CPU,但是仍然能算到死机 (虽然可以 remote access 学校的 cluster 上去,但是浪费学校的资源也不好),所以迫使自己重新学习 R 中的 vectorization,其实比如上面的例子,在 R 中用 vector 作也简单(假设上面 data frame 的名称是dat):

chn<-dat[grep("CHN",dat$ID),]

也挺简单的。所以程序还是一个摸索熟练的过程 ( 虽然我还没有发现如何像 stata 一样便捷的在 R 中的 panel data 里创建 lag variable,并且还在等待大牛人们完善 R 中的 panel data package,譬如 fixed-effect negative binomial model,但是 R 的灵活性,特别是在编程和模拟上,还是超出其他软件很多,特别是 R 是 免费的!)

Free Tags: 
Blog分类: 

开源软件的苦与乐

开源软件的一点感想,不过不是说 Drupal (当然 Drupal 作为开源软件的一种也有同样的问题),而是 R。原本只做数学分析模型,不做统计计量模型,但是无数的 reviewer 都说: 证据呢?好吧,作计量,但是简单的计量回归已经无法满足“人民群众日益增长的复杂要求”,所以做数值模拟,做蒙特卡洛,用到 R,虽然以前没怎么用过,但是编程语言都有相通之处,譬如和 Excel 里的 VBA 相比, loop 或者 flow control 的结构基本相同(除了不用写 end if 或者 next i,略省些力气),再就是把 Cells (i, j) 换成 Mat[i, j] (总之只要把一个 spread sheet 看成一个 matrix,基本的思路都是一样,当然 R 可以直接进行 vector 运算,譬如 elseif,这个要方便很多),做模拟和矩阵运算,R 的效率都很不错,code 也简单,譬如重复 probit 估测一千次,R 里面不过几行代码,不到一分钟的运算,这点比以前常用的 Stata 要好很多 —— 这是开源软件灵活性的好处。

但是作一些简单的操作,却又凸现了开源软件的协调问题 (coordination problem)。举个最简单的例子,在 panel data 里生成 lagged variable。这样的操作在 Stata 里只有一行指令:

gen lag_var=l.var

(当然你要先用 xt 设置好 panel data)。但是在 R 里面,尽管 time-series data 相关 package 里有定义好的 lagged variable 函数,但是在 panel data 相关的 package 里面却没有,因此如果想完成这样一个简单的操作,必须写一个复杂的函数,把需要 lag 的 variable 从panel data 的 data.frame  里按照unit抽出来,设置为 time-series data,然后生成 lagged variable, 再用 cbind 合并回去,然后用 by 按照不同的 unit,再用 rbind 把各个 unit 的生成的 row 合并回去,然后 do.call 。

如果作 dynlm 和作 plm package的人能合作一下,统一做一个根据数据类型生成 lagged variable 的函数岂不是很方便( Stata 里的 laggged variable 指令是同时适用于 time-series data 和 panel-data 的)——也许这就是商业软件的好处吧,至少相互协调的很好。

当然这还不是最麻烦的地方。最麻烦的问题在于开源软件给了你灵活性的同时,也要求你很多东西要 DIY,虽然有很多现成的 package ,但是这些 package 都是大家自愿贡献的,所以不可能要求他非常的全面,当你需要一些 package 里没有的东西的时候,就不得不自己动手了,譬如想对 panel data 作一下 fixed effects poisson/negative binomial regression, plm package 里没有,其他任何的 package 中也没有找到,自己写? 虽然这在 Stata 里只是 xtpoisson / xtnbreg 这么简单,虽然这在技术上也不算太高深(Wooldridge 那本关于 panel data的教科书里有算法),但是从头开始写起恐怕没有一个星期是弄不完,并且问题在于我只是一个打酱油的 –,- … …

结论:开源软件固然好,商业软件离不了:)

Blog分类: