我想根据多个条件对新数据框进行子集/过滤。我尝试了此处提到的以下代码(基于多个条件的子数据框)和(如果至少一个组成员满足条件,则从 data.frame 中删除组)
A small portion of total database:
df<- structure(list(pat_id = c(10302, 10302, 10302,
10482, 10482,10482,
10613, 10613, 10613,
16190, 16190, 16190,
16220, 16220,16220, 16220, 16220, 16220, 16220, 16220),
date = c("2014-04-22","2018-12-13", "2020-07-27", "2019-07-15", "2019-09-19", "2019-09-23",
"2015-09-29", "2015-10-06", "2015-11-20", "2013-07-08", "2018-01-30",
"2020-01-09", "2016-06-15", "2018-02-23", "2019-02-14", "2019-08-09",
"2020-03-02", "2020-07-03", "2020-11-09", "2020-12-16"),
number = c(1,2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 5, 6, 7, 8),
col1 = c(0,1, 1, 2, 4, 4, 9, 3, 1, 0, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9),
col2 = c(NA_real_,NA_real_, NA_real_, 0, 1, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_),
col3 = c(NA_real_,NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_)),
class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -20L), groups = structure(list(
pat_id = c(10302, 10482, 10613, 16190, 16220), .rows = structure(list(
1:3, 4:6, 7:9, 10:12, 13:20), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -5L), .drop = TRUE))
每一行代表一个“联系人”,“号码”列是联系人号码。所以每个 pat_id 都有 1 个或多个联系人。 col1-3 列代表治疗(-选项)。如果 pat_id 在第一个或第二个联系人(编号 1 或 2)的第 1-3 列中具有治疗选项 1,我想从数据集中删除该 pat_id 值。
我尝试根据以下条件创建一个新的数据框。
如果数字为1或2并且col1、col2或col3为1,则删除具有相应id值的所有行。
所需输出:
id date number col1 col2 col3
10613 .. 1 9 NA NA
10613 .. 2 3 NA NA
10613 .. 3 1 NA NA
etc
我已经尝试过
df1 <- df %>% group_by(pat_id) %>% filter(any(!(number <= 2 & (col1 == 1 | col2==1 | col3==1))))
但这似乎不起作用。可能是因为数据框的类/结构吗?我想不通。如果我创建一个具有类似列的“虚拟”数据框,则此代码确实有效。但不是在大数据集上。
有什么建议吗?
首先找到符合第一个条件的行,然后使用
across
查看组内的 any
行是否符合第二个条件
注意:首先取消分组,以便在未分组的数据帧上获得一致的方法。
df <- df %>%
ungroup()
df %>%
filter(!any(number %in% c(1,2) &
any(across(starts_with("col"), ~ .x %in% 1))), .by = pat_id)
# A tibble: 8 × 6
pat_id date number col1 col2 col3
<dbl> <chr> <dbl> <dbl> <dbl> <dbl>
1 16220 2016-06-15 1 9 NA NA
2 16220 2018-02-23 2 9 NA NA
3 16220 2019-02-14 3 9 NA NA
4 16220 2019-08-09 4 9 NA NA
5 16220 2020-03-02 5 9 NA NA
6 16220 2020-07-03 6 9 NA NA
7 16220 2020-11-09 7 9 NA NA
8 16220 2020-12-16 8 9 NA NA