用于检查是否存在相同行,日期减1的函数

时间:2016-06-02 20:16:03

标签: r dplyr

我需要一个函数来检查我的数据框是否有相同的行,但日期减1,如果存在,则返回true。它是一个庞大的数据框架,因此我希望尽可能高效地完成这项工作。

例如,请采用以下数据框:

name  |date       
Timmy |01/Jan/2016
Timmy |02/Jan/2016
Timmy |03/Jan/2016
Sally |04/Jan/2016
Johnny|13/Feb/2016
Johnny|29/Mar/2016

该功能应该看到Timmy|02/Jan/2016,检查Timmy|01/Jan/2016是否存在,然后返回true。结果数据框如下所示:

name  |date       |hasDateMinusOne
Timmy |01/Jan/2016|false
Timmy |02/Jan/2016|true
Timmy |03/Jan/2016|true
Sally |04/Jan/2016|false
Johnny|13/Feb/2016|false
Johnny|29/Mar/2016|false

This is the closest answer I've found.虽然Hadley已经回答了这个问题,但它已经5岁了,并且早于dplyr。我想知道它是否仍然是处理1,000,000多行的最有效方式。

谢谢!

肖恩

2 个答案:

答案 0 :(得分:2)

如果您将date格式化为日期,则可以减去一个:

library(dplyr)

df %>% group_by(name) %>% 
    mutate(date = as.Date(date, '%d/%b/%Y'), 
           hasDateMinusOne = (date - 1) %in% date)

# Source: local data frame [6 x 3]
# Groups: name [3]
# 
#     name       date hasDateMinusOne
#   (fctr)     (date)           (lgl)
# 1  Timmy 2016-01-01           FALSE
# 2  Timmy 2016-01-02            TRUE
# 3  Timmy 2016-01-03            TRUE
# 4  Sally 2016-01-04           FALSE
# 5 Johnny 2016-02-13           FALSE
# 6 Johnny 2016-03-29           FALSE

答案 1 :(得分:1)

我们只能使用base R执行此操作。使用transform将“日期”转换为“日期”类,然后使用ave按“名称”转换,并查找前一天是否找到%in%“日期”列。< / p>

df <- transform(df, date = as.Date(date, "%d/%b/%Y"))
df$hasDateMinusOne <- with(df, !!ave(as.integer(date), name,
            FUN = function(x) (x-1) %in% x))

如果效率很重要,另一种选择是data.table。将'data.frame'转换为'data.table'(setDT(df)),将'date'更改为'Date'类,按'name'分组,我们会发现前一天是否找到%in% '日期'栏。

setDT(df)[, date := as.Date(date, '%d/%b/%Y') 
     ][, hasDateMinusOne := (date-1) %in% date, by =  name]
df
#     name       date hasDateMinusOne
#1:  Timmy 2016-01-01           FALSE
#2:  Timmy 2016-01-02            TRUE
#3:  Timmy 2016-01-03            TRUE
#4:  Sally 2016-01-04           FALSE
#5: Johnny 2016-02-13           FALSE
#6: Johnny 2016-03-29           FALSE