gpt4 book ai didi

r - 使用 data.table 根据 R 中的 B 列有条件地删除 A 列中匹配的行

转载 作者:行者123 更新时间:2023-12-04 12:32:29 26 4
gpt4 key购买 nike

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

A 列是名称列表,其中一些名称出现了多次。 B 列是日期列表。还有许多其他列我也想复制(日期发生在 Name 上的事情。)

但是,我只想查看新数据表中每个人的最多事件,该数据表中每个名称都有 1 个条目,对应于最近的日期。

示例数据

    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 .但是,我不能假设要选择的数据是第一个或最后一个,除非您可以建议一种方法来操纵我的数据,以便在设置 key 后做到这一点。

最佳答案

有很多方法可以在不对数据表进行排序的情况下执行此操作(尽管排序是首选,因为 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(就像您已经做过的那样)并在 duplicated 中指定 from.last = TRUE 并删除 !

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。它的效率最低,但在某些情况下很有用,当您想要返回所有列并且您不能使用 sduplicated

等函数时
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

关于r - 使用 data.table 根据 R 中的 B 列有条件地删除 A 列中匹配的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27159115/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com