#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