R语言 按日期和ID过滤重复项

qpgpyjmq  于 2023-05-04  发布在  其他
关注(0)|答案(2)|浏览(190)

我有一个 Dataframe 如下所示

Id      Date1        Date2        QuestionId   AnswerValue
10      2000-01-14   2000-01-14   1339         3
10      2000-01-14   1999-12-09   1339         2
10      2000-01-14   1999-11-23   1461         1 
10      2000-01-14   2000-01-03   1461         18
10      2000-01-14   1999-11-16   274          0
57      2014-02-01   2014-12-10   278          0
57      2014-02-01   2012-11-07   280          0
57      2014-02-01   2012-09-30   280          0 
57      2014-02-01   2012-01-15   261          0

我的目标是根据以下标准保留观察结果。
1.保留该ID和问题ID组合的行,其中问题ID是唯一的,并且该ID+问题ID组合没有其他重复的问题ID。示例:保留最后一行

Id      Date1        Date2        QuestionId   AnswerValue
57      2014-02-01   2012-01-15   261          0

1.如果每个QuestionID+ID组合都有重复的QuestionID,则仅保留QuestionID中Date 2列值最接近Date 1列值的行,例如:ID 10有两个问题ID 1339。根据此标准,仅应保留第一行,因为与第二行相比,问题ID 1339的Date 2值2000 -01- 14最接近Date 1值2000-01-14,其中Date 2值为1999-12-09,而Date 1值为2000-01-14。

Id      Date1        Date2        QuestionId   AnswerValue
10      2000-01-14   2000-01-14   1339         3

1.删除Date 2值大于Date 1的所有行。例如,应删除第6行
Id日期1日期2问题Id答案值57 2014-02-01 2014-12-10 278 0
最终的数据集看起来像下面这样。

Id      Date1        Date2        QuestionId   AnswerValue
10      2000-01-14   2000-01-14   1339         3
10      2000-01-14   2000-01-03   1461         18
10      2000-01-14   1999-11-16   274          0
57      2014-02-01   2014-12-10   278          0
57      2014-02-01   2012-11-07   280          0
57      2014-02-01   2012-01-15   261          0

任何帮助实现这一点是非常感谢。先谢谢你了。

von4xj4u

von4xj4u1#

这里有一个使用dplyr的想法,

library(dplyr)

df %>% 
  group_by(Id, QuestionId) %>% 
  slice(which.min(difftime(Date1, Date2))) %>% 
  filter(Date2 <= Date1)

#Source: local data frame [5 x 5]
#Groups: Id, QuestionId [5]

#     Id      Date1      Date2 QuestionId AnswerValue
#  <int>     <date>     <date>      <int>       <int>
#1    10 2000-01-14 1999-11-16        274           0
#2    10 2000-01-14 2000-01-14       1339           3
#3    10 2000-01-14 2000-01-03       1461          18
#4    57 2014-02-01 2012-01-15        261           0
#5    57 2014-02-01 2012-11-07        280           0

备注

确保日期列设置为as.Date

6qqygrtg

6qqygrtg2#

使用data.table,首先在标准3(Date2 <= Date1)上进行过滤,然后只返回Date1 - Date2最小的行(即日期彼此最接近),并使用by = .(Id, QuestionId)IdQuestionId的每个唯一组合执行此操作:

library(data.table)
dt <- structure(list(Id = c(10L, 10L, 10L, 10L, 10L, 57L, 57L, 57L, 
57L), Date1 = structure(c(10970, 10970, 10970, 10970, 10970, 
16102, 16102, 16102, 16102), class = "Date"), Date2 = structure(c(10970, 
10934, 10918, 10959, 10911, 16414, 15651, 15613, 15354), class = "Date"), 
    QuestionId = c(1339L, 1339L, 1461L, 1461L, 274L, 278L, 280L, 
    280L, 261L), AnswerValue = c(3L, 2L, 1L, 18L, 0L, 0L, 0L, 
    0L, 0L)), .Names = c("Id", "Date1", "Date2", "QuestionId", 
"AnswerValue"), row.names = c(NA, -9L), class = "data.frame")

setDT(dt)
dt[Date2 <= Date1, .SD[which.min(Date1-Date2)], by = .(Id, QuestionId)]

   Id QuestionId      Date1      Date2 AnswerValue
1: 10       1339 2000-01-14 2000-01-14           3
2: 10       1461 2000-01-14 2000-01-03          18
3: 10        274 2000-01-14 1999-11-16           0
4: 57        280 2014-02-01 2012-11-07           0
5: 57        261 2014-02-01 2012-01-15           0

请注意,在最后的数据示例中,该行不符合第三个标准(Date2 <= Date1):

Id           Date1      Date2     QuestionId   AnswerValue
57      2014-02-01   2014-12-10   278          0

相关问题