查找未来时间范围内的重复用户ID(以R表示)

时间:2019-03-17 20:19:56

标签: r

我有一个用户ID和帐户登录表,该表的运行时间为2017年1月1日至2018年5月1日。这种情况很少见,所以我想看看他们是否每年登录同一日期的+/- 45天(在下面的代码中,我使用的是320/410,除非需要进行此操作,否则我将在稍后进行整理)。

loginID     userID     date
1           a          2017-01-03
2           b          2017-01-12
3           c          2017-01-14
4           d          2017-01-19
5           d          2017-10-18
6           a          2017-11-30
7           b          2017-12-09
8           c          2017-12-17
9           a          2017-12-30
10          b          2018-01-15

我正在尝试编写一个循环,其中表引用了自己。我所拥有的最好的(不工作,但经过几次尝试)是:

for (row in 1:nrow(df)){
    target <- subset(df, date < (row$date+410))
    target <- subset(target, date > (row$date+320))
    target <- target$userID
    df$ninety <- row$userID %in% target
}

我正在寻找的结果是:

loginID     userID     date         repeat_oneyr
1           a          2017-01-03   TRUE
2           b          2017-01-12   TRUE
3           c          2017-01-14   TRUE
4           d          2017-01-19   FALSE
5           d          2017-10-18   FALSE
6           a          2017-11-30   FALSE
7           b          2017-12-09   FALSE
8           c          2017-12-17   FALSE
9           a          2017-12-30   FALSE
10          b          2018-01-15   FALSE

(之所以将2017年10月18日(含2017年10月18日)视为FALSE,是因为我们没有登录数据来表明他们是否在此之后的320到410天之间登录)。

(从其他SO问题/答案中)我知道,如果我可以对每个loginID进行TRUE / FALSE迭代,则可以使用match()来加入数据框,因此我不必担心那部分-首先获得TRUE / FALSE。

欢迎/感谢任何建议。

2 个答案:

答案 0 :(得分:0)

您可以使用data.table做一些事情。首先,我按用户ID排序data.table。其次,我将date列转换为date对象。第三,我使用shift(, type="lead")创建一个fwd_date列。最后,我使用ifelse创建了repeat_oneyr列。

library(data.table)
setDT(df)
setorder(df,userID)
df[,date:=as.Date(df$date)]
df[,fwd_date:=shift(date,type="lead"),by=userID]
df[,repeat_oneyr:=ifelse( (fwd_date-date < 410 & fwd_date-date > 320) 
                           & !is.na(fwd_date) ,TRUE, FALSE)]

    loginID userID       date   fwd_date repeat_oneyr
 1:       1      a 2017-01-03 2017-11-30         TRUE
 2:       6      a 2017-11-30 2017-12-30        FALSE
 3:       9      a 2017-12-30       <NA>        FALSE
 4:       2      b 2017-01-12 2017-12-09         TRUE
 5:       7      b 2017-12-09 2018-01-15        FALSE
 6:      10      b 2018-01-15       <NA>        FALSE
 7:       3      c 2017-01-14 2017-12-17         TRUE
 8:       8      c 2017-12-17       <NA>        FALSE
 9:       4      d 2017-01-19 2017-10-18        FALSE
10:       5      d 2017-10-18       <NA>        FALSE

数据

df<-read.table(text="loginID     userID     date
1           a          2017-01-03
2           b          2017-01-12
3           c          2017-01-14
4           d          2017-01-19
5           d          2017-10-18
6           a          2017-11-30
7           b          2017-12-09
8           c          2017-12-17
9           a          2017-12-30
10          b          2018-01-15",header=T)

答案 1 :(得分:0)

这是一种dplyr的方法:

library(dplyr)

df %>% 
  group_by(userID) %>%
  mutate(date = as.Date(date),
         l45 = lead(between(c(0, diff.Date(date)), 320, 410), default = FALSE))

# A tibble: 10 x 4
# Groups:   userID [4]
   loginID userID date       l45  
     <int> <fct>  <date>     <lgl>
 1       1 a      2017-01-03 TRUE 
 2       2 b      2017-01-12 TRUE 
 3       3 c      2017-01-14 TRUE 
 4       4 d      2017-01-19 FALSE
 5       5 d      2017-10-18 FALSE
 6       6 a      2017-11-30 FALSE
 7       7 b      2017-12-09 FALSE
 8       8 c      2017-12-17 FALSE
 9       9 a      2017-12-30 FALSE
10      10 b      2018-01-15 FALSE