我想通过任意数量的条件(表示为另一个数据帧d
中的行)来递归过滤数据帧z
。
我从数据帧d
开始:
d <- data.frame(x = 1:10, y = letters[1:10])
第二个数据帧z
具有列x1
和x2
,它们是过滤d$x
的上下限。该数据帧z
可能会增长为任意数量的行。
z <- data.frame(x1 = c(1,3,8), x2 = c(1,4,10))
我想返回d
的所有d$x <= z$x1[i]
和d$x >= z$x2[i]
的所有行,其中i
。
因此,对于这个玩具示例,请排除1:1、3:4、8:10(包括1和2)中的所有内容。
i = nrow(z)
答案 0 :(得分:1)
我们可以使用非等额联接
library(data.table)
i1 <- setDT(d)[z, .I, on = .(x >=x1, x <= x2), by = .EACHI]$I
i1
#[1] 1 3 4 8 9 10
d[i1]
# x y
#1: 1 a
#2: 3 c
#3: 4 d
#4: 8 h
#5: 9 i
#6: 10 j
d[!i1]
# x y
#1: 2 b
#2: 5 e
#3: 6 f
#4: 7 g
或使用fuzzyjoin
library(fuzzyjoin)
library(dplyr)
fuzzy_inner_join(d, z, by = c('x' = 'x1', 'x' = 'x2'),
match_fun = list(`>=`, `<=`)) %>%
select(names(d))
# A tibble: 6 x 2
# x y
# <int> <fct>
#1 1 a
#2 3 c
#3 4 d
#4 8 h
#5 9 i
#6 10 j
或者从'd'获取不在'x'中的行
fuzzy_anti_join(d, z, by = c('x' = 'x1', 'x' = 'x2'),
match_fun = list(`>=`, `<=`)) %>%
select(names(d))
# A tibble: 4 x 2
# x y
# <int> <fct>
#1 2 b
#2 5 e
#3 6 f
#4 7 g
答案 1 :(得分:1)
我们可以在x1
和x2
值之间创建一个序列,并使用anti_join
从d
中选择z
中不存在的行。
library(tidyverse)
remove <- z %>%
mutate(x = map2(x1, x2, seq)) %>%
unnest(x) %>%
select(x)
anti_join(d, remove)
# x y
#1 2 b
#2 5 e
#3 6 f
#4 7 g