尝试使用R中的data.table修复重复数据删除问题。

A列是名称列表,其中一些名称会多次出现。 B列是日期列表。我还想复制其他很多列(“日期名称”上发生的事情)。

但是,我只想查看一个新数据表中每个人的最多活动,该数据表的每个名称都有一个与最新日期相对应的条目。

示例数据

    name.last       date
 1:     Adams 2014-10-20
 2:     Adams 2014-07-07
 3:   Barnett 2014-11-06
 4:   Barnett 2014-09-22
 5:      Bell 2014-10-22
 6:      Bell 2014-07-29
 7:     Burns 2014-09-08
 8:     Burns 2014-09-03
 9:   Camacho 2014-08-12
10:   Camacho 2014-07-08
11:  Casillas 2014-10-07
12:  Casillas 2014-07-17
13:    Chavez 2014-09-23
14:    Chavez 2014-09-17
15:   Chavira 2014-07-15
16:   Chavira 2014-07-07
17:    Claren 2014-10-30
18:    Claren 2014-10-23
19:  Colleary 2014-11-11
20:  Colleary 2014-11-07


答案将仅返回每个名字的第一个(因为这里的行按每个名字的最新日期排序。)但是,如果我设置dt键setkey(dt,name.last)以便使用unique()删除重复项,它将重新排序该表按键顺序排列(名称按字母顺序排列)。然后,使用unique(dt)返回每个名称的首次出现,不一定是最近的日期。

如果我在两列setkeyv(dt,c(name.last,date))上都设置了密钥,则由于所有密钥都是唯一的,因此我无法使用unique()删除重复项。

问题类似于这里的一个帖子:Collapsing data frame by selecting one row per group。但是,我不能假定要选择的数据是第一个还是最后一个,除非您可以提出一种在设置密钥后操纵我的数据的方法。

最佳答案

有很多方法可以不对数据表进行排序(尽管优选排序,因为duplicated效率很高,而且您还避免使用by-可以做到这一点)。

首先,必须确保date属于Date类,以便使事情变得更容易

dt[, date := as.Date(date)]


第一种简单方法(虽然不是最有效的)

dt[, max(date), name.last]
#     name.last         V1
#  1:     Adams 2014-10-20
#  2:   Barnett 2014-11-06
#  3:      Bell 2014-10-22
#  4:     Burns 2014-09-08
#  5:   Camacho 2014-08-12
#  6:  Casillas 2014-10-07
#  7:    Chavez 2014-09-23
#  8:   Chavira 2014-07-15
#  9:    Claren 2014-10-30
# 10:  Colleary 2014-11-11


第二种(提供的)方法与您相似,但是使用的是data.tables setorder(对于data.table版本> = 1.9.4),应该是最有效的

setorder(dt, name.last, -date)[!duplicated(name.last)]
#     name.last       date
#  1:     Adams 2014-10-20
#  2:   Barnett 2014-11-06
#  3:      Bell 2014-10-22
#  4:     Burns 2014-09-08
#  5:   Camacho 2014-08-12
#  6:  Casillas 2014-10-07
#  7:    Chavez 2014-09-23
#  8:   Chavira 2014-07-15
#  9:    Claren 2014-10-30
# 10:  Colleary 2014-11-11


您可以使用setkey来实现相同的目的(就像您已经做过的那样),并且在from.last = TRUE中指定duplicated并删除!

setkey(dt, name.last, date)[duplicated(name.last, from.last = TRUE)]

#     name.last       date
#  1:     Adams 2014-10-20
#  2:   Barnett 2014-11-06
#  3:      Bell 2014-10-22
#  4:     Burns 2014-09-08
#  5:   Camacho 2014-08-12
#  6:  Casillas 2014-10-07
#  7:    Chavez 2014-09-23
#  8:   Chavira 2014-07-15
#  9:    Claren 2014-10-30
# 10:  Colleary 2014-11-11


第三种方法是使用data.tableunique函数(它也应该非常有效)

unique(setorder(dt, name.last, -date), by = "name.last")
#     name.last       date
#  1:     Adams 2014-10-20
#  2:   Barnett 2014-11-06
#  3:      Bell 2014-10-22
#  4:     Burns 2014-09-08
#  5:   Camacho 2014-08-12
#  6:  Casillas 2014-10-07
#  7:    Chavez 2014-09-23
#  8:   Chavira 2014-07-15
#  9:    Claren 2014-10-30
# 10:  Colleary 2014-11-11


最后一种方法是使用.SD。它效率最低,但是在某些情况下很有用,当您想返回所有列并且不能使用s duplicated之类的函数时

setorder(dt, name.last, -date)[, .SD[1], name.last]
#     name.last       date
#  1:     Adams 2014-10-20
#  2:   Barnett 2014-11-06
#  3:      Bell 2014-10-22
#  4:     Burns 2014-09-08
#  5:   Camacho 2014-08-12
#  6:  Casillas 2014-10-07
#  7:    Chavez 2014-09-23
#  8:   Chavira 2014-07-15
#  9:    Claren 2014-10-30
# 10:  Colleary 2014-11-11

10-05 21:00
查看更多