r - R tidyverse 中根据另一个数据帧中的范围匹配一个数据帧

标签 r dplyr tidyverse tidyr

我有两个大型数据集想要相互匹配

library(tidyverse)

df1 <- tibble(position=c(10,11,200,250,300))
df1
#> # A tibble: 5 × 1
#>   position
#>      <dbl>
#> 1       10
#> 2       11
#> 3      200
#> 4      250
#> 5      300

df2 <- tibble(start=c(1,10,200,251),
              end=c(20,100,250,350),
              name=c("geneA","geneB","geneC","geneD"))
df2
#> # A tibble: 4 × 3
#>   start   end name 
#>   <dbl> <dbl> <chr>
#> 1     1    20 geneA
#> 2    10   100 geneB
#> 3   200   250 geneC
#> 4   251   350 geneD

reprex package 于 2022 年 3 月 3 日创建(v2.0.1)

我有df1中基因的位置,我想根据范围找到(start-end)df2这个位置可以找到多少个基因。

我希望我的数据看起来像这样

  position start   end name 
     <dbl> <dbl> <dbl> <chr>
1       10     1    20 geneA
2       10    10   100 geneB
3       11     1    20 geneA
4       11    10   100 geneB
5      200   200   250 geneC
6      250   200   250 geneC
7      300   251   350 geneD

解决这个问题的一种方法是通过交叉和过滤

df1 %>% 
  crossing(df2) %>% 
  filter(position >= start & position <= end)

但是我的数据集太大,无法交叉或扩展。还有其他想法吗?

最佳答案

1) SQL引擎无需交叉即可执行此类操作。 (如果添加索引,可能会加快速度。)

library(sqldf)

sqldf("select *
  from df1 a
  join df2 b on a.position between b.start and b.end")

2) data.table还可以做一些类似sql的操作。 (要小心,因为每次比较中的第一个变量必须来自第一个数据表,第二个变量必须来自第二个数据表。它们不能重新排序,因此,例如,第一个比较不能写为position <= start,即使它在数学上是相同的。)同样,添加索引可以提高速度。

library(data.table)

dt1 <- as.data.table(df1)
dt2 <- as.data.table(df2)[, c("start2", "end2") := .(start, end)]
dt2[dt1, on = .(start <= position, end >= position)]

关于r - R tidyverse 中根据另一个数据帧中的范围匹配一个数据帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71337669/

相关文章:

R - Dplyr - 比较最后一行与实际行的值

r - 有关如何使用 for 循环比较列和向量输入的建议

r - 使用 group_by 时发生 mutate_at 评估错误

r - pivot_longer 对于具有相同 names_to 的多个集合

r - 带有 R-plugin 和 LaTeX-Suite 的 Vim 在插入模式下导致反斜杠行为异常

r - 在行 R 中找到相似的数字组

r - 使用 Rcurl 抓取数据

r - 取一列中一起运行的数字的平均值

r - dplyr::过滤器 "No tidyselect variables were registered"

r - 如何基于 R 中的两列创建虚拟对象