前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >R Tricks: 如何巧为观测标记序号

R Tricks: 如何巧为观测标记序号

作者头像
用户7652506
发布2020-10-23 16:27:12
9430
发布2020-10-23 16:27:12
举报

在前面

本期大猫课堂将会开始一个新的系列:你不知道的R Tricks。这个系列将搬运stackoverflow.com(以后简称SO)上关于R数据处理的一些经典问答。大猫除了翻译原文,还会从初学者的角度为代码补充详细的解释。其实这些问题基本上都是大猫自己在数据处理过程中实际遇到的,看了SO上的答案不禁拍案叫绝,忍不住和大家分享。

第一期的主题是:如何巧为观测标记序号?这个问题在事件研究法时经常会遇到,但仅看标题小伙伴们是不是还觉得云里雾里?快点往下看吧!

出问题

话说有个小伙伴在StackOverflow上提出了这样一个问题:假设我现在有这样一个数据集:

建立样例数据集的代码:

▶ set.seed(42)

▶ dt <- data.table(group = sample(0:1, 10000, rep = TRUE), n = 0L)

其中,group的取值只能是0和1, 表示一件事情是否发生。你可以把group理解为一个人是否去健身房,如果连续出现1则意味着那几天每天都去,出现0则说明那人偷懒了。现在的问题是,我希望为每个连续的0或者1编号。例如连续出现3个0, 那么n就标记为1、2、3,如果后面接了一个1, 那么就重新从1开始标记。也即最终的结果应该是:

可以看到,group每变动一回,n就重新计数一次。那么这个代码究竟该怎么写呢?其实只需要一行就够啦!

原问题大家可以访问以下链接:http://stackoverflow.com/questions/25415749/creating-a-sequence-in-a-data-table-depending-on-a-column

决问题

在解决本问题的过程中我们需要用到data.table包!

虽然最终版本的代码只需要一行,但在这里大猫将会把它拆解为三部分:

首先,我们需要有一个变量能标记出group的变化。也就是当group不变时取0,变化时取1。在R中,求差分的函数diff非常适合完成这个任务。它可以计算当前观测和上一行观测相比变化了多少。我们试着用一下:

▶ dt[, diff := c(0, diff(group))]

结果如下:

看,现在每当group发生变化,diff就非零,但是diff只能在0、-1、1中变动,并不能把每次变化都用1、2、3……的数字给标记出来。那如何能够把每次变化都累加起来呢?这时就需要cumsum累加函数:

▶ dt[, cumsum := cumsum(abs(diff))]

结果如下:

看,diff每变化一次,cumsum就把这种变化累加起来了(注意我们用到了abs绝对值函数)。目前为止,我们已经成功把每次变化都分组并加以标号(见cumsum变量),看起来是不是几乎大功告成了?最后一步,我们只需要在每个by=cumsum组中将观测从1开始标号即可:

▶ dt[, n := seq(.N), by = cumsum]

最终结果为:

注意,我们这里用cumsum的值进行了分组,并且用了seq(.N)这个语句。".N"表示当前by组有多少的观测,而seq(.N)则产生从1至.N的一个整数序列。

例如,对于上面的第一行和第二行观测来说,他们同属于cumsum=0这组。因为这组一共只有两行,所以.N=2,而seq(.N)就产生{1, 2}这样一个整数序列,并最终赋值给n。

如果把上面三步写成一行代码就是这个样子:

▶ dt[, n := seq(.N), by = list(cumsum(c(0, abs(diff(group)))))]

期总结

本期大猫带领大家学习了一个为分组观测进行编号的小技巧。还记得在开篇大猫说这个技巧在事件研究法中特别实用吗?因为在事件研法中,我们一般会给事件日标为1,非事件日标为0,对于每个事件之间的一段时间,我们往往希望能够用1开始为其标号,这对于后续统计相当有用。此外,在做一些游程检验的过程中,这个技巧也非常管用。

我是大猫,咱们下期见!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-07-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大猫的R语言课堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档