我经常发现自己拥有代表我想要分析的特定实验的唯一标识符列表。为了加快使用这些实验创建数据子集的过程,我已经将这些列表存储在单独的表中。这些唯一标识符的组合经常会发生变化,具体取决于我正在分析的数据类型,虽然我知道每次都可以编写这样的函数:
library(dplyr)
filter_xy <- function(data, look) {
base <- look %>% mutate(id__ = paste0(x,y)) %>% distinct()
data %>%
mutate(id__ = paste0(x,y)) %>%
filter(id__ %in% base$id__) %>%
select(-id__)
}
我想概括上述函数以使用唯一标识符的任意组合。这样我就可以拥有一个我一直使用的功能:
filter_id(data, look, x, y)
我一直试图解决这个问题,但我还不太了解非标准评估。我认为它应该是这样的,但我不确定。
filter_id <- function(data, look, ...) {
id <- c(...)
base <- look %>%
mutate_(.dots = setNames(list(interp( ~ paste0(id))), "id__")) %>%
distinct()
data %>%
mutate_(.dots = setNames(list(interp( ~ paste0(id))), "id__")) %>%
filter(id__ %in% base$id__) %>%
select(-id__)
}
我很感激任何指导。下面我已经制定了一些示例数据:
lookup.csv
:
g,h
a,a
a,b
b,a
b,b
c,a
c,b
c,c
c,d
test.csv
:
g,h,x,y
a,a,1,10
a,a,2,8
a,b,1,10
a,b,2,8
a,b,3,7
a,c,1,10
a,c,2,9
a,c,3,8
a,c,4,8
a,d,1,10
a,d,2,9
a,d,3,8
a,e,1,10
a,e,2,10
a,e,3,10
b,a,1,10
b,a,2,3
b,b,1,10
b,b,2,5
b,c,1,10
b,c,2,10
b,c,3,10
b,d,1,10
b,d,2,10
c,a,1,10
c,a,2,8
c,b,1,10
c,b,2,9
c,b,3,8
c,b,4,8
c,c,1,10
c,c,2,4
c,d,1,10
d,a,1,10
d,a,2,9
d,a,3,8
d,b,1,10
d,b,2,10
d,b,3,10
d,c,1,10
d,c,2,9
d,c,3,9
d,d,1,10
d,d,2,10
我想编写的代码将test.csv
数据仅归入lookup.csv
数据中的列:
lookup <- read_csv("lookup.csv")
test <- read_csv("test.csv")
test %>% filter_id(lookup, g, h)
结果应仅显示来自ids
的{{1}}中匹配的行。我不能只按lookup.csv
进行过滤,因为特定的组合是我想要选择的,而不是两个独立的条件。
特殊情况函数将是:
g %in% lookup$g & h %in% lookup$h
结果:
filter_gh <- function(data, look) {
base <- look %>% mutate(id__ = paste0(g,h)) %>% distinct()
data %>%
mutate(id__ = paste0(g,h)) %>%
filter(id__ %in% base$id__)
}
答案 0 :(得分:3)
我认为您真的只想使用正确的列(?semi_join
和g
)来h
:
semi_join
返回x中匹配值的所有行,y 只保留x中的列。
半连接与内连接不同,因为内连接将是 为y的每个匹配行返回一行x,其中半连接将为 永远不要复制x行。
对于您的示例,那将是:
semi_join(test, lookup, by = c("g", "h"))
# g h x y
#1 a a 1 10
#2 a a 2 8
#3 a b 1 10
#4 a b 2 8
#5 a b 3 7
#6 b a 1 10
#7 b a 2 3
#8 b b 1 10
#9 b b 2 5
#10 c a 1 10
#11 c a 2 8
#12 c b 1 10
#13 c b 2 9
#14 c b 3 8
#15 c b 4 8
#16 c c 1 10
#17 c c 2 4
#18 c d 1 10
如果您将数据存储为factor
变量,则可能会出现警告。