【问题标题】:Remove duplicate dates based on a separate column根据单独的列删除重复的日期
【发布时间】:2014-06-10 18:06:13
【问题描述】:

我的数据头部看起来像:

     IndID Event       Date
148   P01     1 2011-03-04
147   P01     1 2011-03-11
149   P01     0 2011-03-13
150   P01     0 2011-03-14
151   P01     0 2011-03-14
152   P01     0 2011-03-14  

有 3 个人(P01、P03、P06)。 “事件”指定是否发生事件(0=否,1=是) “日期”为监控日期。

我的目标是根据每个人的“事件”列删除重复的日期。如果存在重复且未发生事件(给定日期的所有事件值均为 0),则应删除重复项且事件应保持为 0。当存在重复日期且已发生事件时(意味着至少有一个事件值是 1),然后我尝试删除重复项并为给定日期保留一行,在事件列中为 1。

虽然this 的帖子很有用,但我正在寻找更多细节。目前,我正在努力解决可能过于复杂且没有必要的嵌套for() 循环。

任何建议将不胜感激!我的数据如下:

如果相关,一旦我为每个人设置了一个日期,我希望通过将序列(从每个人的第一个日期到最后一个日期)与我现有的数据合并来添加缺少的日期并添加事件列中的 0 到新条目。

DP <- structure(list(IndID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L), .Label = c("P01", "P02", "P03", "P05", "P06", "P07", 
"P08", "P09", "P10", "P11", "P12", "P13"), class = "factor"), 
    Event = c(1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    1L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 
    0L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 
    1L, 1L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 1L, 1L
    ), Date = structure(c(1299196800, 1299801600, 1299974400, 
    1300060800, 1300060800, 1300060800, 1300147200, 1300320000, 
    1300406400, 1300406400, 1300492800, 1300492800, 1300665600, 
    1300924800, 1301097600, 1302048000, 1302134400, 1302220800, 
    1302652800, 1302825600, 1302998400, 1303084800, 1303171200, 
    1303257600, 1303689600, 1303862400, 1304208000, 1304380800, 
    1304553600, 1304640000, 1305072000, 1305590400, 1305676800, 
    1305676800, 1305676800, 1305763200, 1305936000, 1306022400, 
    1306022400, 1306108800, 1306368000, 1323129600, 1323388800, 
    1323648000, 1323993600, 1324080000, 1324166400, 1324339200, 
    1327622400, 1327622400, 1327795200, 1327881600, 1327881600, 
    1328486400, 1328659200, 1328832000, 1329177600), class = c("POSIXct", 
    "POSIXt"), tzone = "GMT")), .Names = c("IndID", "Event", 
"Date"), row.names = c(148L, 147L, 149L, 150L, 151L, 152L, 153L, 
51L, 52L, 154L, 53L, 155L, 145L, 156L, 157L, 373L, 382L, 384L, 
361L, 385L, 349L, 387L, 386L, 388L, 341L, 360L, 339L, 334L, 366L, 
340L, 363L, 352L, 351L, 353L, 355L, 397L, 336L, 337L, 354L, 335L, 
371L, 475L, 417L, 472L, 492L, 494L, 493L, 473L, 468L, 497L, 495L, 
486L, 499L, 470L, 487L, 496L, 469L), class = "data.frame")

【问题讨论】:

    标签: r for-loop merge


    【解决方案1】:

    实际上,您并没有太多删除重复项,而是您只是在汇总。听起来您只需要每个人的每个日期的最大事件值(如果有事件,则为 1,否则为 0)。

    aggregate(Event~Date+IndID, DP, max)
    

    这应该可以解决问题。如果您还有其他数据列要跟踪,请尝试此方法

    inddate <- with(DP, ave(Event, Date, IndID, 
        FUN=function(x)seq_along(x)==which.max(x)))
    DP[inddate==1, ]
    

    【讨论】:

    • 我们非常感谢您的建议,并且非常准确。事实上,简单地聚合是一种更好的方法。最上面的代码是完美的。第二次运行,但它遗漏了一天 - 这意味着每个美洲狮从开始到结束的序列中都有一天的间隙。有什么想法吗?如上所述,我的想法是将现有数据框与新创建的日期序列合并。
    • @B.Davis 第二部分错过了几天是正确的,因为它只创建至少一个主题发生观察的日子的值。您与完整日期列表合并的想法听起来不错。
    • 跟进问题。将“聚合”函数应用于具有公式中未使用的附加列的较大数据集时,如何将它们包含在新的(聚合的)数据表中?结果表仅包含公式中的列,我在帮助文件中没有看到 all = T 或类似内容。提前致谢!
    • @B.Davis 不幸的是,拥有不适合 max 函数的其他列会使事情变得更加困难。我已经用一种不同的子集方法更新了我的答案,该方法将保留所有其他列。
    • 哇!谢谢一堆。非常有创意,内容丰富且乐于助人。干杯!
    猜你喜欢
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2020-06-22
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多