dplyr 查找表/模式匹配

Mar*_*rco 5 r lookup-tables dplyr

我一直在寻找一种聪明的或“更整洁”的方式来利用 tidyverse 中的查找表,但找不到令人满意的解决方案。

我有一个数据集和查找表:

# Sample data
data <- data.frame(patients = 1:5,
                   treatment = letters[1:5],
                   hospital = c("yyy", "yyy", "zzz", "www", "uuu"),
                   response = rnorm(5))

# Lookup table
lookup <- tibble(hospital = c("yyy", "uuu"), patients = c(1,5))
Run Code Online (Sandbox Code Playgroud)

...其中查找表中的每一行都是我想要过滤第一个小标题(数据)的确切模式。

想要的结果如下所示:

# A tibble: 3 x 4
  patients treatment hospital response
     <dbl> <chr>     <chr>       <dbl>
1     1.00 a         yyy       -0.275 
2     5.00 e         uuu       -0.0967
Run Code Online (Sandbox Code Playgroud)

我想出的最简单的解决方案是这样的:

as.tibble(dat) %>% 
  filter(paste(hospital, patients) %in% paste(lookup$hospital, lookup$patients))
Run Code Online (Sandbox Code Playgroud)

然而,这一定是很多人经常做的事情 - 有没有一种更干净、更方便的方法来做到这一点(即,对于查找表中的两列以上)?

Len*_*ski 5

由于 的默认行为dplyr::inner_join()是匹配传递给函数的两个 tibbles 之间的公共列,并且查找表仅包含 2 个关键列,因此最短的代码如下:

library(dplyr)

# Sample data
data <- tibble(patients = 1:5,
                   treatment = letters[1:5],
                   hospital = c("yyy", "yyy", "zzz", "www", "uuu"),
                   response = rnorm(5))

# Lookup table
lookup <- tibble(hospital = c("yyy", "uuu"), patients = c(1,5))

data %>% inner_join(.,lookup)
Run Code Online (Sandbox Code Playgroud)

...以及输出:

> data %>% inner_join(.,lookup)
Joining, by = c("patients", "hospital")
# A tibble: 2 x 4
  patients treatment hospital response
     <dbl> <chr>     <chr>       <dbl>
1     1.00 a         yyy        -1.44 
2     5.00 e         uuu        -0.313
>
Run Code Online (Sandbox Code Playgroud)

因为所需的输出可以通过跨 tibbles 的关键列进行连接来完成,所以paste()OP 中的代码是不必要的。

另请注意,这inner_join()是正确的联接类型,因为所需的输出是在两个传入 tibbles 之间匹配的行,并且查找表没有重复的行。如果查找表包含重复的行,那么semi_join()根据 OP 上的注释,这将是适当的函数。