删除 R 数据框中重复的行,组中第一个,与组中第一个共享 ID 或以上所有
Remove rows in R dataframe that are duplicates, first in group, share ID with first in group or all of the above
我有一个包含日期和标识符的数据框。我想过滤此数据框以结束具有 1) 原始数据框中其他人的连续日期的行,2) 不是一组连续日期中的第一个,3) 与行的 ID 不同在第一个日期之后的一组连续日期中的第一个,4) 基于 ID 进行重复数据删除。例如
Date <- as.Date('2019.01.01', '2019.01.02', '2019.01.03', '2019.01.04', '2019.01.10', '2019.01.11', '2019.01.12', '2019.01.13', '2019.01.18', '2019.01.22', '2019.01.27', ' 2019.01.28', '2019.01.30')
ID <- c('A', 'A', 'C', 'C', 'D', 'E', 'A', 'F', 'D', 'F', 'F', 'C', 'G')
df <- data.frame(Date, ID)
Date ID
2019.01.01 A
2019.01.02 A
2019.01.03 C
2019.01.04 C
2019.01.10 D
2019.01.11 E
2019.01.12 A
2019.01.13 F
2019.01.18 D
2019.01.22 F
2019.01.27 F
2019.01.28 C
2019.01.30 G
以
结束
Date ID
2019.01.03 C
2019.01.11 E
2019.01.13 F
不胜感激!
首先我们定义元素,它们是“组中的第一个”:
library(dplyr)
library(lubridate)
first_of_groups <- df %>%
mutate(Date = as_date(Date)) %>%
group_by(grp_cond_3 = cumsum((Date - lag(Date, default = first(Date))) != 1)) %>%
filter(n() > 1) %>%
slice_min(Date)
我们需要这个 data.frame 来删除这个元素。接下来我们构建 data.frame:
df %>%
mutate(Date = as_date(Date),
condition_1 = Date == lag(Date) + 1,
condition_2 = replace_na(condition_1, FALSE)) %>%
left_join(first_of_groups, by = "ID", suffix = c("", ".y")) %>%
mutate(condition_3 = is.na(Date.y) | Date < Date.y) %>%
ungroup() %>%
filter(condition_1, condition_2, condition_3) %>%
group_by(ID) %>%
slice(1) %>%
select(Date, ID) %>%
ungroup()
这个returns
# A tibble: 3 x 2
Date ID
<date> <chr>
1 2019-01-03 C
2 2019-01-11 E
3 2019-01-13 F
基本上condition_1
和condition_2
是一样的。我们取日期并计算与前一个日期的差异。如果差异等于 1,我们知道两件事:
- 它不是一组连续天数的第一个元素
- 连续几天
对于“first of groups”条件,我们在您的数据集中搜索与前一行的差异不为 1 的行。假设没有具有相同日期的行,我们可以构建使用此信息中的 cumsum
建立一个分组号码。
接下来我们过滤“真实”组,即具有多个元素的组。然后我们取这些组的第一个元素。
使用这个 first_of_groups
data.frame 我们可以通过左连接 first_of_groups
和我们的原始数据框来构建 condition_3
。满足 condition_3
first_of_groups
data.frame (is.na(Date.y)
) 中的 ID
不匹配或日期为 lesser/smaller(位于) ID
成为“小组第一”的日期。
最后的 condition_4
是通过在剩余的 data.frame 中取每个 ID
的第一个元素创建的。
我有一个包含日期和标识符的数据框。我想过滤此数据框以结束具有 1) 原始数据框中其他人的连续日期的行,2) 不是一组连续日期中的第一个,3) 与行的 ID 不同在第一个日期之后的一组连续日期中的第一个,4) 基于 ID 进行重复数据删除。例如
Date <- as.Date('2019.01.01', '2019.01.02', '2019.01.03', '2019.01.04', '2019.01.10', '2019.01.11', '2019.01.12', '2019.01.13', '2019.01.18', '2019.01.22', '2019.01.27', ' 2019.01.28', '2019.01.30')
ID <- c('A', 'A', 'C', 'C', 'D', 'E', 'A', 'F', 'D', 'F', 'F', 'C', 'G')
df <- data.frame(Date, ID)
Date ID
2019.01.01 A
2019.01.02 A
2019.01.03 C
2019.01.04 C
2019.01.10 D
2019.01.11 E
2019.01.12 A
2019.01.13 F
2019.01.18 D
2019.01.22 F
2019.01.27 F
2019.01.28 C
2019.01.30 G
以
结束 Date ID
2019.01.03 C
2019.01.11 E
2019.01.13 F
不胜感激!
首先我们定义元素,它们是“组中的第一个”:
library(dplyr)
library(lubridate)
first_of_groups <- df %>%
mutate(Date = as_date(Date)) %>%
group_by(grp_cond_3 = cumsum((Date - lag(Date, default = first(Date))) != 1)) %>%
filter(n() > 1) %>%
slice_min(Date)
我们需要这个 data.frame 来删除这个元素。接下来我们构建 data.frame:
df %>%
mutate(Date = as_date(Date),
condition_1 = Date == lag(Date) + 1,
condition_2 = replace_na(condition_1, FALSE)) %>%
left_join(first_of_groups, by = "ID", suffix = c("", ".y")) %>%
mutate(condition_3 = is.na(Date.y) | Date < Date.y) %>%
ungroup() %>%
filter(condition_1, condition_2, condition_3) %>%
group_by(ID) %>%
slice(1) %>%
select(Date, ID) %>%
ungroup()
这个returns
# A tibble: 3 x 2
Date ID
<date> <chr>
1 2019-01-03 C
2 2019-01-11 E
3 2019-01-13 F
基本上condition_1
和condition_2
是一样的。我们取日期并计算与前一个日期的差异。如果差异等于 1,我们知道两件事:
- 它不是一组连续天数的第一个元素
- 连续几天
对于“first of groups”条件,我们在您的数据集中搜索与前一行的差异不为 1 的行。假设没有具有相同日期的行,我们可以构建使用此信息中的 cumsum
建立一个分组号码。
接下来我们过滤“真实”组,即具有多个元素的组。然后我们取这些组的第一个元素。
使用这个 first_of_groups
data.frame 我们可以通过左连接 first_of_groups
和我们的原始数据框来构建 condition_3
。满足 condition_3
first_of_groups
data.frame (is.na(Date.y)
) 中的 ID
不匹配或日期为 lesser/smaller(位于) ID
成为“小组第一”的日期。
最后的 condition_4
是通过在剩余的 data.frame 中取每个 ID
的第一个元素创建的。