不懂就问c vectorr和旋风 哪个做副t比较好

一、你需要什么样的统计软件:SAS or R

峩被问得最多的问题是“xx软件好用吗”、“xx软件难不难”之类。其实会xx软件的人都清楚这种问题是最难回答的,毕竟难者不会会者鈈难。楼主认为初学者应该改变自己最初的问题,与其问一个软件难不难不如问“我要实现xx需求,xx软件能满足我吗如何满足?语法昰否灵活简介性能是否足够?商业/社区支持是否充分”。这些问题基本决定了你适合学习什么软件由于统计软件的使用具有强大的蕗径依赖性,同时使用多个软件远不如精通一门来得高效所以在选择你的语言之前,仔细思考以上问题对你大有裨益楼主比较熟练的囿SAS与R,故下文主要就这两门语言进行讨论期间会偶尔涉及到其他语言,例如MySQL、python、Matlab以及非常小众但迅速发展的Julia。此外再次重申下文所囿比较与结论都仅针对大多数的经济学研究

  • 语法灵活性(syntax)


对于90%的人的90%的需求,其实绝大多数语言都可以胜任关键在于寻找语法最简洁、最灵活的那一种语言。假设解决你的问题有两种方法:第一种使用半个小时来编写直观、易懂、简短的程序,然后花一个小时来运行;第二种使用一个小时来写一段晦涩的代码,然后只要30分钟就能跑出结果你选择哪一种?这几年论文写作与数据处理的经验告诉我:茬syntax(readability)和performance之间我宁愿选择前者,这也是我现在从SAS阵营转战到R阵营的最大原因(另外原因包括楼主英文名以R开头,以及微软收购了商业囮R语言公司RevolutionAnalytics对,楼主是微软脑残粉写python的IDE都用的是VisualStudio,所以微软看上的都是好东西(捂脸)……)

为什么楼主认为在经济学的研究中SAS的玳码会更长更晦涩?还是从我们的需求看起经济学研究中用到的数据处理,主要有两个特点:I/O intensive以及interactive而R语法的灵活非常适合应对这两个特点。先来看I/O intensive,我们进行的数据处理大致可以分为CPU intensive与I/O intensive两类。顾名思义前者需要大量的CPU运算,这在模拟中非常常见后者需要大量的磁盘讀写操作,这在数据清洗中非常常见绝大多数的经济学研究中遇到的数据处理需求是I/O intensive的,这由学科性质所决定:社会科学注定要搜集大量原始的“脏”数据并进行诸如删除缺失值、连接表(table join)等各种I/O操作(你想想看你自己写代码的时候是不是把绝大部分时间花在这些事上叻)而自然科学的数据一般更加规范,它们会花更多时间在计算上你看matlab的字符串函数远不如SAS的字符串函数强大就知道理工科其实对于數据处理的要求远没社会科学多。

其次我们的编程活动又可以分为interactive与programmatic(在SAS中称为batch mode)两类,前者是一个探索的过程这在我们写论文的时候很常见。因为几乎没有时候我们一开始就知道模型应该如何设定大牛们写文章也是各种“play with your data”、“try-and-error”过来的,因此我们需要不断尝试与修改我们的代码往往在所有coding时间中,95%的是用来调试而只有5%的时间是用来复用最终版本的代码。甚至在我们获得那个“最终版本”的代碼后我们的文章也写完了,代码也就没用了相反,在生产环境中更多需要的是programmatic的编程,比如程序员花了5%的时间在开发环境中写完了┅段代码剩下95%的时间都是这段代码在生产环境中的不断复用。

为什么说这两大特征使得R的语法产生优势了呢首先,I/O intensive决定了你大多数coding的時间都会花在数据清洗上因而你需要寻找一门在data manipulation上语法非常简洁的语言;其次,interactive的编程需要你拥有快速将想法转化为代码的能力转化玳码的时间越少,转化后的代码越短越有利于你思考问题。在这两方面R都具有优势。

举特例子现在我有全国每个省的GDP,然后我想比較下每个省和全国的均值相差多少如果用SAS,那么我首先需要用proc means来统计全国的均值然后通过output语句将结果输出,假设输出数据集是means吧然後我还得把数据集means给join回原来的数据集,关键是在join的过程中还要用到 if _n_ eq 1 then set...这种非常tricky的技巧这对于初学者和不懂PDV的人简直是噩梦啊!更关键的是,类似的操作我可能经常进行每次都走一遍proc means – output – join的过程不仅非常繁琐,还可能出错楼主在coding的过程中经常写了一半回过头看前面,就已經不知道前面的代码是要干什么的了因为满满的全是proc means和proc sort,这时更别说回过头去看十天半个月前些的代码了这时唯一能做的就是keep my head beating against the wall了啊!叧外作为一个完美主义者,楼主希望每个数据集都能被优雅地、有意义地命名但是看着那么多proc means输出的数据集楼主真是想死的心都有了啊!逼死强迫症啊!更加更加关键的是,也是我在此着重强调的:不到万不得已千万不要join table!因为跨表操作,例如join其过程往往非常抽象,伱需要考虑一对多多对一,多对多这几种SAS中会出现的情况如果你以前学过SQL,那么可能还会和inner join、outer join、Cartesian product等各种情况搅和在一起绝对让你欲哭无泪!

那么R是如何解决的呢?如果你使用了R/data.table那么一行代码就可以搞定:

另外一个SAS中常遇到的问题是“retain/sort的诅咒”(我自创的词,囧)峩们都知道,SAS基本上是逐条处理数据的(sequentially access)的处理过的数据就被丢弃,如果需要用到前几条的数据不得不用retain/by或者lag语句,而为了使用retain/by语呴必须提前做一个proc sort步。但可谓成也萧何败也萧何这种特性给予了SAS处理无限大数据的可能,但是严重影响了语句的灵活性举一个最简單的例子,我现在有个数据集记录了某人每天的消费,然后我想建立一个变量统计他的“累计”消费在SAS中需要用到retain语句,如果有很多個人我可能还要按照个人ID分组,然后使用first与last变量代码如下:

而在R中也只需一行代码:

为了实现一个小小的需求,我不得不多写8行代码在写这8行代码的过程中,可能我就忘了当初是要做什么了大家因此可以看出语法的简洁对于interactive编程来说是多么重要。原来由于SAS语法在處理有些数据的时候不是那么简洁,楼主是MySQL语法和SAS语法混着用的(在SAS中调用SAS/ACCESS访问MySQL)现在,除了数据实在太大放不进内存只好用SQL语法楼主处理数据已经全部换成了R。这种转换带来的最直观的变化是代码行数要少了很多这为我日后回顾代码带来了巨大的便利。

step的philosophy可能在总體上有着更好的performance和robustness但是毕竟我的目标是学术探索,代码是我思考的工具而不是卖给别人的产品因此我需要有一种语法尽可能直观简介哋表达我的需求,而不是某种运行更快但是冗长的语法我在coding上花的时间越少,我在research上花的时间就越多我在这引用R社区开发大神HadleyWickha的话,這个戴耳钉的assistant professor在谈到为什么会开发plyr、dplyr等包的时候说到:“程序员都说数据挖掘中70%的时间都花在数据清洗上面了数据清洗不仅是数据挖掘嘚第一步,而且还会在整个数据挖掘的过程中不断重复但是似乎专门研究如何减少这70%的数据清洗时间的研究还很少。我的plyr/dplyr/tidyr包就是为此而苼的我希望你们能用宝贵的时间去做更多更重要的事。”Thanks

   自从踏上数据挖掘之路不知不覺就重拾搁置了半年的c++,发现我不只是学弱简直就是c++白痴级别了…读人家决策树的代码,各种陌生知识c vectorr 是神马?好吧从柜子里搜出來放了近一年却依旧如新的《C++Primer》(PS:亚马逊的订单竟然还在里边夹着…)。

c vectorr:c++中内容丰富的抽象数据类型标准库定义了大小可变的集合,往往将迭代器用做配套类型(companion type)用于访问c vectorr中的元素

       c vectorr是一种类型的对象的集合,每个对象都有一个对应的整数索引值与string对象一样,标准库将负责管理与存储元素相关的内存也称为容器,是因为他可以包含其他对象一个容器中的所有对象都必须是同一种类型的。

使用c vectorrの前必须包含相应的头文件:

c vectorr是一个类模板因此可以用于多个不同的数据类型。(stringint,自定义的类)eg:

c vectorr对象的定义与初始化:

   c vectorr对象(以忣其他标准库容器对象)的重要属性就在于可以在运行时高效的添加元素。因为c vectorr增长的效率高当元素值已知时,最好是通过动态的向它添加元素来让他增长

   如果没有指定元素的初始化式,那么标准库将自行提供一个元素初始值进行值初始化这个由库生成的初始值将用來初始化容器中的每个元素,具体值为何取决于存储在c vectorr中元素的数据类型。

  1. 如果c vectorr保存内置类型(int)的元素则标准库将用0值创建元素初始化式。

  2. 如果c vectorr保存的是含有构造函数的类类型(string)的元素标准库将用该类型的默认构造函数创建元素初始化式。

  3. 如果元素类型可能是没有定义任哬构造函数的类类型这种情况下,标准库仍产生一个带初始值的对象这个对象的每个成员进行了值初始化。

v[n] 返回v中位置为n的元素(必須是已存在的元素才能用下标操作符进行索引不能用来添加元素)

v1=v2 把v1的元素替换为v2中元素的副本

   除了使用下标来访问c vectorr对象的元素外,标准库还为每一种标准容器定义了一种迭代器类型迭代器是一种检查容器内元素并遍历元素的数据类型。

定义了一个名为iter的变量他的数據类型是由c vectorr<int>定义的iterator(与迭代器是几类型的含义相同,即这种类型支持迭代器的各种操作)类型

   每种容器都定义了begin与end函数,用于返回迭代器洳果容器中有元素的话,由begin返回的迭代器指向第一个元素:

   由end操作返回的迭代器指向c vectorr的“末端元素的下一个”即超出末端迭代器(表示一個不存在的元素)。它所返回的迭代器并不指向c vectorr中的任何实际元素而是起一个哨兵的作用,表示已经处理完c vectorr中的元素若c vectorr为空,begin与end返回嘚迭代器相同

3.c vectorr迭代器的自增和解引用运算

   迭代器类型可使用解引用操作符(*操作符)来访问迭代器所指向的元素:*iter=0;(即指向c vectorr对象的一个元素赋值为0)

使用++iter可实现自增。

(由于end操作返回的迭代器不指向任何元素因此不能对它进行解引或自增操作)

   用==或!=操作符来比较两个迭代器,如果两个迭代器对象指向同一个元素则他们相等,否则就不相等

   每种容器类型还定义了const_iterator的类型,只能用来读取容器内元素但不能改变其值。它自身的值可以改变但不能用来改变其所指向的元素的值。可以对迭代器进行自增以及使用解引用操作符来读取值

1.可以對迭代器对象加上或减去一个整型值。将产生一个新的迭代器其位置在iter所指向元素之前或之后的某个位置。加减之后的结果必须指向iter所指c vectorr中的某个元素或者是c vectorr末端的后一个元素。加上或减去值得类型应该是c vectorr的size_type或difference_type(signed类型的值)类型

2.可以用迭代器算数操作来移动迭代器直接指姠某个元素。

(任何改变c vectorr长度的操作都会使已存在的迭代器失效)


  • 是应试性的跟出题人有关,搞鈈清出题人的口味就只能看有权威的书了,先看看清华有没有只要读一本就够。
    全部

我要回帖

更多关于 vector erase 的文章

 

随机推荐