基于 R 中的多个条件过滤观察结果

问题描述 投票:0回答:1

我有以下数据集:

library(dplyr)

df <- data.frame(
  id = c(1,1,1,1, 2,2,2, 3,3,3,3, 4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5),
  code = c(rep(5, 26)),
  week_num = c(1101, 1102, 1104, 1105, 1101, 1102, 1103, 1101, 1102, 1103, 1104, 1151, 1152, 1201, 1202, 1203,
               1101, 1102, 1103, 1114, 1115, 1116, 1117, 1118, 1119, 1120)
  )

我有 5 个人,他们的 ID、代码和日期格式为 yyww(即)11 是年份,01 是 2011 年的第一周。

我想要的是创建一个代码,其中:

  1. 第一个人将被排除在外,因为他没有 4 次代码 5,因为本周休息(即缺少 1103)

  2. 第二个人将被排除在外,因为他只有 3 次代码 5,而我们希望某人至少有 4 次或更多次拥有代码 5

  3. 第三个人将被包括在内,因为他至少有4次代码5并且同一年内连续几周

  4. 第四个人也将被包括在内,因为他至少有4次代码5,并且尽管年份发生变化(从2011年到2012年),但周数是连续的

  5. 第五个人也将被包括在内,因为尽管他在日期中有中断,但在中断之后他至少出现了代码 5 4 次

此代码将创建一个名为 code_found 的新变量,该变量将正确识别每个参与者的 week_num 的第一周/第一年作为值(即,即使年份发生变化,代码变量中也连续至少有 4 倍的代码 5)或几周之间有中断)

有没有办法用 dplyr 来计算它?这是我的数据集的一个小例子。我从 2009 年到 2017 年还有很多年,所以代码 5,有时连续一年,但我希望它至少出现 4 次或更多 #因此,如果可能的话,代码必须以某种方式通用以匹配我的原始数据。

期望的输出是:

id   code    code_found
3      5        1101
4      5        1151
5      5        1114

提前致谢

r dplyr filter
1个回答
0
投票

在这里,我将

yywk
值转换为日期,以便更容易计算。然后我计算行之间的天数,将 NA 替换为 7,以便我们可以过滤以仅保留全部为 7 且至少有 4 行的组。

library(tidyverse)
df |>
  separate(week_num, c("yr", "wk"), 2) |>
  mutate(date = as.Date(paste0(yr, "-", wk, "-1"), "%y-%U-%u")) %>%
  mutate(contig = coalesce(as.numeric(date - lag(date)), 7), .by = id) %>%
  filter(all(contig == 7), n() >= 4, .by = id)

Result

  id code yr wk       date contig
1  3    5 11 01 2011-01-03      7
2  3    5 11 02 2011-01-10      7
3  3    5 11 03 2011-01-17      7
4  3    5 11 04 2011-01-24      7
5  4    5 11 51 2011-12-19      7
6  4    5 11 52 2011-12-26      7
7  4    5 12 01 2012-01-02      7
8  4    5 12 02 2012-01-09      7
9  4    5 12 03 2012-01-16      7
© www.soinside.com 2019 - 2024. All rights reserved.