如何删除在 R 中不完全重复的行

Posted

技术标签:

【中文标题】如何删除在 R 中不完全重复的行【英文标题】:how delete rows which are not completely duplicated in R 【发布时间】:2022-01-12 11:20:30 【问题描述】:

我有数据示例

第一个

resp=structure(list(person_number = c(914198L, 914198L, 914198L, 914198L, 
914198L, 957505L, 957505L, 957505L, 957505L, 957505L, 967216L, 
967216L, 967216L, 967216L, 967216L, 27771498L, 27771498L, 27771498L, 
27771498L, 27771498L, 957505L, 957505L, 957505L, 914198L, 967216L, 
967216L, 914198L, 967216L, 914198L), position_code = c(50000690L, 
50000690L, 50000690L, 50000690L, 50000690L, 50000690L, 50000690L, 
50000690L, 50000690L, 50000690L, 50000690L, 50000690L, 50000690L, 
50000690L, 50000690L, 801L, 801L, 801L, 801L, 801L, 50000690L, 
50000690L, 50000690L, 50000690L, 50000690L, 50000690L, 50000690L, 
50000690L, 50000690L), date = c(7L, 2L, 1L, 4L, 5L, 6L, 3L, 4L, 
5L, 2L, 3L, 5L, 1L, 6L, 7L, 7L, 2L, 6L, 4L, 1L, 6L, 3L, 4L, 1L, 
3L, 5L, 4L, 7L, 5L), start_hour = c(9L, 9L, 11L, 9L, 9L, 9L, 
9L, 11L, 9L, 9L, 9L, 11L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 12L, 
15L, 10L, 9L, 11L, 10L, 11L, 10L, 9L), end_hour = c(21L, 21L, 
21L, 15L, 15L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 
19L, 19L, 19L, 19L, 19L, 21L, 21L, 19L, 21L, 21L, 21L, 21L, 21L, 
21L)), class = "data.frame", row.names = c(NA, -29L))

让我展示一个清晰的示例,以便您了解我需要帮助的内容。 数据集代表和person_number = 957505

person_number   position_code   date    start_hour  end_hour
957505  50000690    6   9   21
957505  50000690    3   9   21
957505  50000690    4   11  21
957505  50000690    5   9   21
957505  50000690    2   9   21
957505  50000690    6   12  21
957505  50000690    3   15  21
957505  50000690    4   10  19

这里我们看到 date = 6 出现了 2 次,范围是 from 9-21 and from 12-21 我们还看到 date = 4 也出现了 2 次,范围 start-end hours 11-21,11-19 这意味着我需要随机删除具有重复日期但范围不同的观察。 即我需要删除日期 = 6 的任何一项观察和日期 = 4 的任何一项

这样

person_number   position_code   date    start_hour  end_hour

957505  50000690    3   9   21
957505  50000690    5   9   21
957505  50000690    2   9   21
957505  50000690    6   12  21
957505  50000690    3   15  21
957505  50000690    4   10  19

但是,也有这样的情况

person_number   position_code   date    start_hour  end_hour
957505  50000690    6   9   21
957505  50000690    3   9   21
957505  50000690    4   11  21
957505  50000690    5   9   21
957505  50000690    2   9   21
957505  50000690    6   12  21
957505  50000690    3   15  21
957505  50000690    4   10  19

我们看到,例如,这里 date = 3 有重复 1 range start_hour end_hour from 9-21, and another 15-21 但是此 person_number 的 15-21 范围不再重复,但 9-21 对于此person_number 重复超过 2 次​​p>

957505  50000690    6   9   21
957505  50000690    3   9   21

957505  50000690    5   9   21
957505  50000690    2   9   21

它在这里出现了 4 次,所以对于 date = 3,我们删除 9-21。因为 15-21 的范围没有重复 2 次或更多次。它必须留下。 对于未指定的任何其他条件,这部分代码适用 这里我们看到 date = 6 出现了 2 次,范围是 from 9-21 and from 12-21 我们还看到 date = 4 也出现了 2 次,范围 start-end hours 11-21,11-19 这意味着我需要随机删除具有重复日期但范围不同的观察。 即我需要删除日期 = 6 的任何一项观察和日期 = 4 的任何一项 我怎样才能通过这样的条件删除行? 任何帮助表示赞赏。谢谢。

【问题讨论】:

【参考方案1】:

这是一个如何使用库 dplyr 进行此类过滤的想法:

library(dplyr)

# resp2 will contain all rows with at least double dates
multiple_date <- resp %>% count(person_number, date) %>% filter(n>1)
resp2 <- semi_join(resp, multiple_date)
# show all of resp2
resp2
# show difference between resp and resp2
anti_join(resp, resp2)

# compare resp with resp2 specifically for person 957505
resp %>% filter(person_number == 957505)
resp2 %>% filter(person_number == 957505)

# resp3 will contain all rows with at least double hour range
multiple_hour <- resp %>% count(person_number, start_hour, end_hour) %>% filter(n>1) 
resp3 <- semi_join(resp, multiple_hour)

# compare resp with resp3 specifically for person 957505
resp3 %>% filter(person_number == 957505)
resp %>% filter(person_number == 957505)

# resp4 will contain all rows that have at least double date and at least double hour range
resp4 <- semi_join(semi_join(resp, resp2), resp3)

# compare resp with resp4 specifically for person 957505
resp4 %>% filter(person_number == 957505)
resp %>% filter(person_number == 957505)

# remove rows that have at least double date and at least double hour range
final <- anti_join(resp, resp4)

# compare resp with final specifically for person 957505
final %>% filter(person_number == 957505)
resp %>% filter(person_number == 957505)

# check how many entries with double date have been left
final %>% count(person_number, date) %>% filter(n>1)

【讨论】:

,谢谢。 # 比较 resp 和 resp2 专门针对 person 957505 如何为所有人做,而不是专门针对 .你能编辑答案吗? 只需在命令行中输入resp2,您将看到resp2 中的所有数据,而不是针对单个人进行过滤。 resp2 和原始 resp 之间的区别是 anti_join(resp, resp2)。如果给出的答案是正确的,请将其标记为正确答案,以便其他读者识别。 我接受了,谢谢。很好。但不明白,你可以编辑你的答案。在哪里输入 resp2

以上是关于如何删除在 R 中不完全重复的行的主要内容,如果未能解决你的问题,请参考以下文章

如何删除R中两列中具有相同值但ID不同的行[重复]

如何从文本文件中删除重复并包含某些单词的行?

如何删除所有重复项以使 NONE 留在数据框中?

删除数据框中引用另一个 (R) 中不存在的 ID 的行?

EXCEL函数 如何删除某一列中不含某一元素的行

R删除冗余行数据基于dplyr包