Categories
日常应用

关于R的若干SQL等价问题

以前总是觉得不同的计算机语言之间只是语法问题,思路其实还是差不多的--后来才知道不尽然如此。比如用惯了R作分析,切换到其他语言顿时觉得效率降低了好多,尤其是很多一行命令在R里面就可以搞定的时候-思维习惯了一定程度的跳跃,常用的操作(尤其是数据整理!)封装成函数之后工作效率那叫一个倍增啊!结合knitr,原来的时候生成定期报告的效率极其之高,基本属于10倍以上的时间节省。

现在公司的数据平台是teradata,典型的SQL结构,各种join。在这么大的数据量下,不可能直接取数据到本机来分析,只能借助SQL进行一定程度的降维。而后剩下的收尾分析工作,可以由R完成。至于两者之间分工的界限在哪里,我还在摸索一个效率最高的平衡点。不得不吐槽一下,SQL的逻辑思维方式真心没效率,完全是为了数据库性能和空间单位平衡而设计的,做分析的时候就额外的痛苦许多——90%以上的时间都用来琢磨怎么鼓捣出来自己需要的数据格式,全在数据清理上了!

抱怨完毕,除了祈祷hadoopR和oracle连接起来彻底摆脱SQL阴影之外,暂时只能跟SQL硬战。下面说说最近常见的几个相同功能在R和SQL里面分别的实现方法。

1. 生成新变量

多见的明确的任务啊。如果是数值型,比如变量D是其他三个变量ABC的显性函数f(A,B,C),最简单诸如D=A+B+C,在R和SQL里面都是直接写。

  • R:
    my_dataframe$D <- my_dataframe$A+ my_dataframe$B + my_dataframe$C

    (当然还有更elegant的with()函数)

  • SQL(以select为例):
    SELECT A,B,C, A+B+C D from my_datatable;

    然后如果f()稍稍复杂的话,R的可以定义函数的优势就明显了,SQL只有macro模式显然不足够灵活强大。如,

R:

generate_D <- function(VarA=A, VarB=B, VarC=C) {
VarD <- VarA * VarB *(VarB %*% VarC)
return( VarD)}
my_dataframe$D <- generate_D(my_dataframe$A, my_dataframe$B, my_dataframe$C)

注:%*%代表向量内积或矩阵乘法,这里为一个数字。理论上这里可以调用任何R中函数。

如果新变量是字符型,R的优势就更明显了,字符串操作函数例如substr()取字符串其中一段,paste()连接多个字符串,grep()和sub()查找替换类,自然比SQL灵活的多。还是那句话,只要能用函数写出来,R都可以方便地搞定。你问我拿SQL跟R比这个有意思么?明显SQL就不是为了这个功能专门设计的啊。好吧,常见的生成新变量的情况:有条件的生成新变量,比如年龄分组等,基本就是按照若干已知条件生成一个新的变量。这里,SQL的case when确实方便,比如年龄分为老中青三组:

SQL:

SELECT CASE WHEN AGE>50 THEN 'old'
WHEN AGE between 25 and 50 THEN 'mid'
ELSE 'young'
END AGE_GROUP
FROM my_datatable

而R中,我一直用一种最笨的办法-刚刚搜了一下发现其实我的办法还是挺好用的。

My_dataframe$AGE_GROUP <- 'young'
My_dataframe[My_dataframe$AGE > 50,]$AGE_GROUP <- 'mid'
My_dataframe[(My_dataframe$AGE >=25 )& (My_datafame$AGE<= 50),]$AGE_GROUP <- 'mid'

当然也可以用ifelse()或者transform的方法,我倒是觉得没有这种笨办法清晰简洁易读,易于回头看代码。ifelse那堆括号哦!没有高亮匹配会死人的。

这里边界值随意,不考虑直接除法取整的情况。两种分类时可以直接用逻辑型简化,一行出结果;另,数值型离散化转换为factor型其实可以简单的用一个函数cut()搞定..(多谢yihui一语道破天机)

2. 分组加总等数据整理统计

要知道在很多时候,什么都比不上基本的求和均值方差有用,偶尔来个计数最大最小值就不错了。SQL一个group by 就神马都搞定了,比如对每组顾客购买的图书本书去重、求和。
SQL:

SELECT sum(TA.quantity) quantity ,
TB.book_type
FROM Table_A TA
OUTER JOIN Table_B TB
ON TA.book_id = TB.book_id
GROUP BY book_type

 

SELECT user_group, SUM(book_quantity) quantity, count(distinct book_id) sold_book
FROM my_datatable
GROUP BY user_group

那么相对应的,在R中,我们的解决策略是万能的data.table()。
R:

book_stat <- data.table(my_dataframe)[,list(quantity=sum(book_quantity), sold_book = length(unique(book_id))), by="user_group]

也不麻烦对嘛~可是,R里面还是有可以调用多种函数的优势哦。嘻嘻。

3. 表的连接和数据混合

咳咳,thanks to 著名的三大范式,SQL语句永远逃不掉各种各样的连接,内外左右,inner join, outer join, left join, right join 写来写去有没有!R里面呢,类似于SAS,有个神奇的merge()函数。每次看到讲left join 的教程示例的时候都觉得真心罗嗦难懂,相比而言R的merge()函数简洁明了了许多有木有!

依旧,假设我们第一个表, 两个字段 book_id, book_quantity, 然后第二个表两个字段,book_id, book_type,包含的是书的分类信息。现在需要分类统计书的数量。

SQL:

这里用外链接,既如果图书在TB中没有分类信息,会自动归于NULL这一列。

用R呢,嘻嘻,很简单。

Book_stat <- merge(TableA, TableB, by="book_id", all.x=T, all.y=T)

这里其实可以简写all=TRUE (T 在R中等价于逻辑值TRUE),只是为了更清晰所以把x,y分开了。多明显啊,我就是要保留两个表中所有的观测对象,如果任意表缺失标记为NA即可。很简单的,merge()的参数和四大连接的关系就是:
INNER JOIN 等价于 merge(all=F)
LEFT JOIN 等价于 merge(all.x=T, all.y=F)
RIGHT JOIN 等价于 merge(all.x=F, all.y=T)
OUTER JOIN 等价于 merge(all=T)

嗯啊,反正对我来说,这个更好理解...

至于SQL的where和having条件,基本就是R中对于行的选择,不再赘述,参见新变量生成那里对于行的选择。TOP或者limit也可以通过head或者直接指定行序号n:m来搞定。其他的常见的就不多了吧...过去两周的时间,我基本就在用R的整理数据框架思路来实现SQL语句撰写的煎熬中度过,多少次烦的时候都想直接砸了显示器或者哀叹如果能导出到R里面该多好...磨合期啊。

注:我现在理解SQL架构还有一项主要的feature就是索引,哈希表是个很强大的东东。这东西某种程度上类似R中factor类型的数据,但是貌似水要深很多,为了提升性能值得继续好好研究。

注2:NOSQL架构拯救分析师啊

注3:数据整理绝对是最耗分析师时间的活,如果思路不清晰不知道想要进入分析模型的数据长什么样子,那就真的悲剧了,往往一天两天就是徒劳。这也是我的小册子新版第一章加的就是数据整理,血泪的教训啊。
另外一个耗时间的就是excel或者word中作图配文字,这个绝对需要knitr来拯救-亲,对于每个分类统计是很简单,但是对于每个分类都画图的话,您难道还准备告诉excel作循环?然后一张张复制粘贴到word里面?省省时间吧,knitr会save your life的,绝对是工欲善其事,必先利其器。分析不是也不应该是体力活哦。下周的上海R沙龙,一定要好好称赞一下knitr,相比于 reproducible research,它对于业界的意义就在于没有BI系统之前,自动写报告...轻量化高效工具!

注4:ipad果然不适合码代码...有typo或不满排版的,容我稍后电脑上修改。

注5:开始研究RHadoop,各种沦落伤不起啊。

Categories
事儿关经济

社会性学习

呃,我着实不知这个social learning应该怎么翻译,姑且翻译成社会性学习吧。最近在看一本书《Learning and expectations in macroeconomics》,是当时Thijs推荐的,因为当时我想找一些有关expectation的东西看看。嗯,容许我小小的残念一下,要是呆在UPF,Thijs一定是我首选的advisor——这或许和我一贯以来选导师的特殊标准有关吧,大牛不见得是适合自己的,我只是想找一个可以不时“点通”我一下的,嗯……唉,不过想想因此而转macro,还是底气不足。不过也就是在这里残念一下了,Ph.D不是眼下需要关注的事儿了。

原来一直很好奇learning到底是被怎么model的,今天终于硬着头皮打开了这本书,看了两章,大概搞明白这东西是被用一个随机过程模拟的(这个,我不清楚数学上的随机过程怎么定义的,我看这本书上的很像时间序列里面的那些东西,有个随机扰动项然后给一个相对的law of motion)。然后看来看去,前面还比较简单,一个均衡唯一的蛛网模型,然后大概说了一下理性预期均衡(rational expectation equilibria,下简称理性预期为RE)为什么在长期中会成为均衡(大意是即在一个有界集内,当t趋近于正无穷时,期望序列收敛于真值)。从这个角度上讲,多多少少有点从数学模型方法上对RE辩白的味道。我不是很喜欢RE,但是特别想知道的是在什么情况下RE确实是可以被满足的,从而可以大大的简化模型。

说到Law of motion,其实就是个动态的发展过程的问题。原来没想太多这个social learning里面的social到底扮演了什么角色,现在琢磨一下social learning果然是从social这个角度去研究人们的学习行为的。呃,我原来其实一直在想,既然是对信念的不断更新,为什么不用贝叶斯法则?我从逻辑上还是蛮欣赏贝叶斯学派的,抑或可能是当年在微观中被PBE毒害太深,一直念念不忘经典的贝叶斯法则。后来琢磨了一下信念(belief)和期望(expectation)确实也还不是一回事儿,所以当我们认为加总(aggregation)可以进行的时候,描述一个社会的学习行为可能不见得非得用贝叶斯法则。这本书上提到了最小二乘法,大意就是给定一个law of motion的线性形式,当人们对其中的参数未知的时候,在每个时期都按照least square来估计一下,然后不断的更新估计,最终还是会收敛到真值。希望我的理解偏差不是太大(先祈祷一下,别在这里纯粹胡说八道就好,我刚开始看这部分的东西,真的不够熟络!),然后我就在想,如果简单的aggregation不可进行的时候,那么又会是什么情况呢?当agents数量不多的时候,显然我们不会天真的去进行加总,那么跟game theory结合点又在哪里呢?可能最近是想把social network一些简单的分析考量找个地方实践一下,所以开始重温IO里面那些经典的例子,比如上周那个exclusive dealing,嗯……

我现在特别好奇的想知道,这个social distance引入到IO里面会有什么好玩的结果。嗯,明天找Motta闲扯去,但愿他不会觉得我太无聊或者异想天开……回到毕业论文,现在大致的有个思路,到底在哪里弄个应用。这次我想show的是有些情况下不能简单的aggregation,所以一直在锲而不舍的寻找一个context(突然发现,有些词儿真的不知道怎么译为中文了,总感觉翻译了就少了点什么了似的)。然后一起做这个东西的同学suggest了一个health belief model,我估计他是看我一直对belief念念不忘,然后就随便扔给我一个跟health有关的model然后我就开始不断的瞎想换他几天的清净时光吧?嗯,我发现我缠人的时候还真是蛮缠人的,不管是在国内国外、中文英文、父母同学,呃,反正当我发现什么东西特别有意思的时候,就会长出一副巨厚的脸皮来不断的缠啊缠,直到缠出来什么好玩的东西为止,整一个小孩子的心态嘛!

想想从前年Winston第一次提及social network在marketing里面的应用,到现在,已然一年半多的时间了。虽然得刨去大四下半年的悠晃时日,但是我接触social network也显然不是一天两天的事儿了。一直在想这么长的时间里,虽然一直没有机会系统的学习一遍,但是在整日的耳濡目染中,我到底被影响了什么?当年Laffont一本incentive theory,直接向我打开了IO的窗户,让我有机会一窥其中奥妙。而今,这种被点燃的感觉,会不会再次重演?我一直有点小小的野心,不想只是从技术层面整合social network,而希望在分析层面亦加以整合。可惜,社会网络显然还没有如经济学一般融入我的血液、骨髓,知其然,但是还不够运用自如,尚需时日打磨啊!

最后说个小插曲。最近一直在被教育,因为原来写论文的时候,就算是有个partner,大都也是一人为主。大概最省心的partner就是导师了吧,自己鼓捣的差不多了,就去找导师扯扯,然后继续回家打磨。这次合作,真的是两个人一起建模,呃,我以前还真没想过原来两个人的合作可以深入到如此的层次,还没树立分析框架呢,就已经开始热火朝天的讨论不休了。不过有利必有弊,这样虽然可以最大程度上的整合两人的知识,但另一方面交流成本自然很高。我,我,我很无奈的今天滔滔不绝了一下午我对建模的观点,比如怎么开始、怎么确立假设之类的,然后不断的回答各种扔过来的arguement。折腾了一个多小时,累死我了。我从来没想过会跟别人谈这些最基本的问题,可能就是太基本了吧,都深深的印在心里了,所以一般就是俯拾即是,没想过那么多为什么。好在最后我没有很丢人的犯什么逻辑错误,最后人家接受了我的各种答案,然后还顺便提高了他对于这个项目的期望。Expectation啊,呃,update的还挺快的。话说,原来一直觉得我计量学的不好,现在发现有些东西还是不知不觉学进去了,今天居然两番拿计量的道理来说一般性的理论角度的建模,真的是有意思。

春暖花开,眼见就五月份了。可知“春风又绿江南岸”,却不见“春来江水绿如兰"。或许是时日,多忆一些江南了。

200933903833_2