根据动态依赖的两个条件过滤
Filter according to two conditions that are in dynamic dependence
我有一个大型数据集,其值为 CPE
,百分比为 PERC
。在现实世界中它略有不同,但我将其减少到最低限度。
| CPE| PERC|
|---:|---------:|
| 42| 0.1132664|
| 264| 0.9260718|
| 470| 0.3732287|
| 316| 0.7437126|
| 9| 0.5819554|
| 114| 0.2052649|
现在我要筛选。较小的 CPE
需要较高的 PERC
才能聚焦。
我当然可以这样做:
df[(CPE > 20 & PERC > 0.95) |
(CPE > 50 & PERC > 0.9) |
(CPE > 100 & PERC > 0.85) |
(CPE > 250 & PERC > 0.8)]
但由于现实世界中可能有更多,而且它们会不时变化,我正在寻找更简单、更动态的解决方案。
比如创建一个包含所有组合的列表,然后将每个组合用作过滤条件对。
list(c(20, 0.95), c(50, 0.9), c(100,0.85), c(250,0.8))
有没有聪明的方法来处理这个问题?即使我更喜欢 data.table
,dplyr
也很棒。它不是一个列表,我愿意接受任何类似的方法。
MWE
library(data.table)
set.seed(33)
df = data.table(CPE=sample(1:500, 100),
PERC=runif(min = 0.1, max = 1, n=100))
如果 list
已经创建,我们可以遍历 list
,使用 CPE
和 PERC
列创建第一个和第二个元素的逻辑条件分别 Reduce
与 |
的单个逻辑向量和数据子集
df[Reduce(`|`, lapply(lst1, \(x) CPE > x[1] & PERC > x[2]))]
数据
lst1 <- list(c(20, 0.95), c(50, 0.9), c(100,0.85), c(250,0.8))
library(dplyr, warn.conflicts = FALSE)
#> Warning: package 'dplyr' was built under R version 4.1.2
library(purrr)
df <- structure(list(CPE = c(42L, 264L, 470L, 316L, 9L, 114L), PERC = c(0.1132664,
0.9260718, 0.3732287, 0.7437126, 0.5819554, 0.2052649)), row.names = c(NA,
-6L), class = "data.frame")
constraints <- structure(list(CPE = c(20, 50, 100, 250), PERC = c(0.95, 0.9,
0.85, 0.8)), class = "data.frame", row.names = c(NA, -4L))
constraints
#> CPE PERC
#> 1 20 0.95
#> 2 50 0.90
#> 3 100 0.85
#> 4 250 0.80
filt <-
map2(df, constraints, outer, '>') %>%
reduce(`&`) %>%
as.data.frame %>%
reduce(`|`)
df %>%
filter(filt)
#> CPE PERC
#> 1 264 0.9260718
由 reprex package (v2.0.1)
于 2022-06-03 创建
我有一个大型数据集,其值为 CPE
,百分比为 PERC
。在现实世界中它略有不同,但我将其减少到最低限度。
| CPE| PERC|
|---:|---------:|
| 42| 0.1132664|
| 264| 0.9260718|
| 470| 0.3732287|
| 316| 0.7437126|
| 9| 0.5819554|
| 114| 0.2052649|
现在我要筛选。较小的 CPE
需要较高的 PERC
才能聚焦。
我当然可以这样做:
df[(CPE > 20 & PERC > 0.95) |
(CPE > 50 & PERC > 0.9) |
(CPE > 100 & PERC > 0.85) |
(CPE > 250 & PERC > 0.8)]
但由于现实世界中可能有更多,而且它们会不时变化,我正在寻找更简单、更动态的解决方案。
比如创建一个包含所有组合的列表,然后将每个组合用作过滤条件对。
list(c(20, 0.95), c(50, 0.9), c(100,0.85), c(250,0.8))
有没有聪明的方法来处理这个问题?即使我更喜欢 data.table
,dplyr
也很棒。它不是一个列表,我愿意接受任何类似的方法。
MWE
library(data.table)
set.seed(33)
df = data.table(CPE=sample(1:500, 100),
PERC=runif(min = 0.1, max = 1, n=100))
如果 list
已经创建,我们可以遍历 list
,使用 CPE
和 PERC
列创建第一个和第二个元素的逻辑条件分别 Reduce
与 |
的单个逻辑向量和数据子集
df[Reduce(`|`, lapply(lst1, \(x) CPE > x[1] & PERC > x[2]))]
数据
lst1 <- list(c(20, 0.95), c(50, 0.9), c(100,0.85), c(250,0.8))
library(dplyr, warn.conflicts = FALSE)
#> Warning: package 'dplyr' was built under R version 4.1.2
library(purrr)
df <- structure(list(CPE = c(42L, 264L, 470L, 316L, 9L, 114L), PERC = c(0.1132664,
0.9260718, 0.3732287, 0.7437126, 0.5819554, 0.2052649)), row.names = c(NA,
-6L), class = "data.frame")
constraints <- structure(list(CPE = c(20, 50, 100, 250), PERC = c(0.95, 0.9,
0.85, 0.8)), class = "data.frame", row.names = c(NA, -4L))
constraints
#> CPE PERC
#> 1 20 0.95
#> 2 50 0.90
#> 3 100 0.85
#> 4 250 0.80
filt <-
map2(df, constraints, outer, '>') %>%
reduce(`&`) %>%
as.data.frame %>%
reduce(`|`)
df %>%
filter(filt)
#> CPE PERC
#> 1 264 0.9260718
由 reprex package (v2.0.1)
于 2022-06-03 创建