Удалить дубликаты, появляющиеся в течение определенного периода времени

#r

#r

Вопрос:

У меня есть набор данных, содержащий переменную ID, дату и несколько агентов (см. Пример ниже). Агенты были протестированы несколько раз для каждого пациента, и я хочу отфильтровать для каждого идентификатора первый появившийся и удалить все остальные тесты, появляющиеся в течение 4 недель после первого. После этого я снова хочу отфильтровать первый и удалить все остальные, появляющиеся в течение 4 недель — по всему набору данных. Я также сгенерировал переменные, показывающие неделю, месяц и год.

 ID <- rep(1, times = 20)
Date <- c("2010-12-09", "2010-12-09", "2010-12-09", "2010-12-09", "2010-12-09", "2010-12-09", "2010-12-09", "2010-12-09", "2010-12-27", "2010-12-27", "2010-12-27", "2010-12-27", "2011-01-14", "2011-01-14", "2011-01-14", "2011-01-14", "2011-01-14", "2011-01-14", "2011-01-14", "2011-01-14")
Agent <- c("Agent1", "Agent2", "Agent3", "Agent4", "Agent1", "Agent2", "Agent3", "Agent4", "Agent1", "Agent2", "Agent3", "Agent4", "Agent1", "Agent2", "Agent3", "Agent4", "Agent1", "Agent2", "Agent3", "Agent4")

df <- data.frame(ID, Date, Agent)


     ID Date        Week Month Year  Agent
1    1  2010-12-09  49   12    2010  Agent1
2    1  2010-12-09  49   12    2010  Agent2 
3    1  2010-12-09  49   12    2010  Agent3 
4    1  2010-12-09  49   12    2010  Agent4 
5    1  2010-12-09  49   12    2010  Agent1 
6    1  2010-12-09  49   12    2010  Agent2 
7    1  2010-12-09  49   12    2010  Agent3
8    1  2010-12-09  49   12    2010  Agent4
9    1  2010-12-27  52   12    2010  Agent1
10   1  2010-12-27  52   12    2010  Agent2
11   1  2010-12-27  52   12    2010  Agent3
12   1  2010-12-27  52   12    2010  Agent4
13   1  2011-01-14  2    1     2011  Agent1
14   1  2011-01-14  2    1     2011  Agent2
15   1  2011-01-14  2    1     2011  Agent3
16   1  2011-01-14  2    1     2011  Agent4
17   1  2011-01-14  2    1     2011  Agent1
18   1  2011-01-14  2    1     2011  Agent2
19   1  2011-01-14  2    1     2011  Agent3
20   1  2011-01-14  2    1     2011  Agent4
  

и что мне нужно, так это:

      ID Date        Week Month Year  Agent
1    1  2010-12-09  49   12    2010  Agent1
2    1  2010-12-09  49   12    2010  Agent2 
3    1  2010-12-09  49   12    2010  Agent3 
4    1  2010-12-09  49   12    2010  Agent4 
13   1  2011-01-14  2    1     2011  Agent1
14   1  2011-01-14  2    1     2011  Agent2
15   1  2011-01-14  2    1     2011  Agent3
16   1  2011-01-14  2    1     2011  Agent4
  

Я рад любой помощи!

Ответ №1:

Вы можете вычесть минимум Date для каждого ID , чтобы создать новую группу, состоящую из данных за 4 недели, и выбрать строки с минимальной датой для каждой ID , group и Agent .

 library(dplyr)

df %>%
  mutate(Date = as.Date(Date)) %>%
  group_by(ID) %>%
  mutate(group = ceiling(as.integer(difftime(Date, min(Date), units = 'week')/4))) %>%
  group_by(ID, group, Agent) %>%
  slice(which.min(Date))

#     ID Date       Agent  group
#  <dbl> <date>     <chr>  <dbl>
#1     1 2010-12-09 Agent1     0
#2     1 2010-12-09 Agent2     0
#3     1 2010-12-09 Agent3     0
#4     1 2010-12-09 Agent4     0
#5     1 2011-01-14 Agent1     1
#6     1 2011-01-14 Agent2     1
#7     1 2011-01-14 Agent3     1
#8     1 2011-01-14 Agent4     1
  

Комментарии:

1. Не уверен, понимаю ли я. Разве 4 недели с 2011-01-14 не совпадают с 8 неделями с 2010-12-09?

Ответ №2:

Вы можете попробовать следующее. Он использует data.table. Я надеюсь, что вы не возражаете, что я не включаю год, месяц, неделю и индекс строки.

 ID <- rep(1, times = 20)
Date <- c("2010-12-09", "2010-12-09", "2010-12-09", "2010-12-09", "2010-12-09", "2010-12-09", "2010-12-09", "2010-12-09", "2010-12-27", "2010-12-27", "2010-12-27", "2010-12-27", "2011-01-14", "2011-01-14", "2011-01-14", "2011-01-14", "2011-01-14", "2011-01-14", "2011-01-14", "2011-01-14")
Agent <- c("Agent1", "Agent2", "Agent3", "Agent4", "Agent1", "Agent2", "Agent3", "Agent4", "Agent1", "Agent2", "Agent3", "Agent4", "Agent1", "Agent2", "Agent3", "Agent4", "Agent1", "Agent2", "Agent3", "Agent4")

df <- data.frame(ID, Date, Agent)

library(data.table)

df=as.data.table(df)
# convert Date
df$Date=as.Date(df$Date)
# drop duplicate lines
df=unique(df)
df$weeks_from_min_date=5 # checked rows will have weeks_from_min<=0

while (max(df$weeks_from_min_date)>0){
  # get min date per Agent-ID of not checked rows
  min_date_per_Agent_ID=df[weeks_from_min_date>=5][,.(min_date=min(Date)),by=.(Agent,ID)]
  # join with df
  df=merge(df,min_date_per_Agent_ID)
  # update weeks_from_min_date
  df$weeks_from_min_date=difftime( df$Date,df$min_date, units = "weeks")
  df=df[df$weeks_from_min_date<=0 | df$weeks_from_min_date>4 ]
  df$min_date=NULL
}
df$weeks_from_min_date=NULL
keycol <-c("Date","Agent")
setorderv(df, keycol)
df