微信号:gh_a9d9c3cb1ca5

介绍:市面上的教材太水?学了半天还是不知道如何处理工作中的数据?大猫的R语言课堂每期都和你分享一个工作研究中的实际问题,期期干货,就是这么实在!

【进阶】Next N rows when condition is

2017-05-07 00:52 大猫

题引入

本期的问题来自于stackoverflow.com,由于大猫实在想不出简洁的翻译,想来想去还是原标题最能描述问题,所以干脆直接借用。如果硬要翻译的话,大概就是“当某条件成立时,找到这个观测后N行的观测”


举个例子吧!



在这个数据集中,我们希望每当condition=1时,就标记出它接下来的2行(这里N=2了)。例如,在以上数据集第4行的condition是1, 那么我们能够标记出第5行以及第6行。又由于第6行的分组从a变成了b,所以只有第5行被标记了出来。具体小伙伴们一看desireOutcome的输出就明白了。


看起来似乎无从下手?其实,要实现这一步只需要一行代码哦。


附:生成样例数据集的文件:


# dt是样例数据集,一共有15行。

# a是分组变量;

dt <- data.table(a = rep(c("a", "b", "c"), each = 5))


# condition是条件;desireOutcome是希望获得的结果

dt[, condition := as.numeric(.I %% 4 == 0)]


本文需要用到data.table包!


骤分解

我们先把这一行优雅的代码放上来:


dt[, desiredOutcome := Reduce('+', shift(condition, 0:2, fill = 0)), by = a]


现在我们逐一分析这一行代码。


shift函数

它能够对向量进行lag与lead操作。参数0:2的意思是分别滞后0期、1期、2期。参数fill的意思是对于leading missing value,使用0进行补齐。需要注意shift最后输出的是一个list,因为我们生成了三个拥有不同滞后期的向量。例如,如果我们有个向量

v <- c(1, 2, 3, 4, 5)

那么使用下面代码

shift(v, 0:2, fill =0)

生成的结果就是这样:


对于原数据集,如果我们删掉Reduce函数,只保留shift函数

dt[, shift(condition, 0:2, fill = 0), by = a]

那么生成的结果就是这样:


其中,V1-V3分别表示对condition变量滞后0,1,2期的结果


Reduce函数

重点来了!在使用shift函数后,我们实际上生成了三个向量,第一个向量只有条件成立时才为1, 第二个向量条件成立后的“滞后一期”才为1, 第三个向量只有条件成立后的“滞后两期”才为1。于是很自然的,如果我们能将这三个向量相加,那么所有符合要求的行就都是1, 不符合的就都是0了。关键问题在于如果给我们一个list,使用什么方法能够把list的每个元素“一一对应”地加总呢?这时我们就需要用到Reduce函数。它的参数“+”相当于把上图的V1-V3列进行加总并生成新的变量。


综上,完整代码就是:


dt[, desiredOutcome := Reduce('+', shift(condition, 0:2, fill = 0)), by = a]


如果想了解更多,可以看stackoverflow.com上的原文:



http://stackoverflow.com/questions/36766452/r-data-table-find-next-n-rows-when-condition-is-true



 

大猫的R语言课堂


我是大猫,我是一个高中读文科但却在代码、数学的路上狂奔不止的Finance Ph. D Candidate。


我的微信号是iRoss2007


我的R语言课堂关注R语言、数据挖掘以及经济金融学。


我与大家分享我的知识,我相信独乐乐不如众乐乐


我还有许多好玩的计划。


更多的精彩内容正在路上。

长按二维码关注
 
大猫的R语言课堂 更多文章 【速览】微软2017春季教育产品线发布会 Azure云中配置R Server 10行代码搞定【滚动回归】 一行代码搞定分组回归 如何批量导入搜狗词库?
猜您喜欢 原生开发才是王道 2016 最可能成功的 10 个开源项目 谈到日本家居品牌,别再只知道无印良品了! 农村金融打通最后一公里,看APM如何助力提升用户体验? web前端规范目的