对于列中的每个值,检查它是否属于另一个 Dataframe 中的任何区间

ds97pgxw  于 2023-04-09  发布在  其他
关注(0)|答案(3)|浏览(98)

假设我有一个位置值列表:

> head(jap["POS"])
      POS
1  836924
2  922009
3 1036959
4 141607615
5 164000000 
6 118528028 
[...]

和间隔列表:

> genes_of_interest
       MGAM        SI      TREH    SLC2A2  SLC2A5   SLC5A1  TAS1R3       LCT
1 141607613 164696686 118528026 170714137 9095166 32439248 1266660 136545420
2 141806547 164796284 118550359 170744539 9148537 32509016 1270694 136594754

我想检查第一个 Dataframe 中的每个位置,如果它在第二个 Dataframe 中的任何间隔内。
所以在这种情况下我应该

FALSE FALSE FALSE TRUE FALSE TRUE

由于141607615属于第一个区间(MGAM),118528028属于第三个区间(TREH)。
你知道怎么做吗?
先谢谢你。

rggaifut

rggaifut1#

在dplyr 1.1.0及更高版本中,如果你首先将genes_of_interest转换成一个整洁的格式,你可以使用一个非等长的left_join()。这将非常快,如果你还有其他列要连接,这将非常灵活。

library(dplyr, warn.conflicts = FALSE)
library(tidyr)

jap <- tibble(
  POS = c(836924, 922009, 1036959, 141607615, 164000000, 118528028)
)

genes_of_interest <- tribble(
  ~MGAM, ~SI, ~TREH, ~SLC2A2, ~SLC2A5, ~SLC5A1, ~TAS1R3, ~LCT,
  141607613, 164696686, 118528026, 170714137, 9095166, 32439248, 1266660, 136545420,
  141806547, 164796284, 118550359, 170744539, 9148537, 32509016, 1270694, 136594754
)

# Manipulate `genes_of_interest` into a tidy data format
genes_of_interest <- genes_of_interest %>%
  mutate(bound = c("start", "end")) %>%
  pivot_longer(-bound) %>%
  pivot_wider(names_from = bound, values_from = value) %>%
  mutate(match = TRUE)

genes_of_interest 
#> # A tibble: 8 × 4
#>   name       start       end match
#>   <chr>      <dbl>     <dbl> <lgl>
#> 1 MGAM   141607613 141806547 TRUE 
#> 2 SI     164696686 164796284 TRUE 
#> 3 TREH   118528026 118550359 TRUE 
#> 4 SLC2A2 170714137 170744539 TRUE 
#> 5 SLC2A5   9095166   9148537 TRUE 
#> 6 SLC5A1  32439248  32509016 TRUE 
#> 7 TAS1R3   1266660   1270694 TRUE 
#> 8 LCT    136545420 136594754 TRUE

jap %>%
  left_join(
    genes_of_interest,
    by = join_by(between(POS, start, end)),
    multiple = "any"
  ) %>%
  mutate(match = !is.na(match))
#> # A tibble: 6 × 5
#>         POS name      start       end match
#>       <dbl> <chr>     <dbl>     <dbl> <lgl>
#> 1    836924 <NA>         NA        NA FALSE
#> 2    922009 <NA>         NA        NA FALSE
#> 3   1036959 <NA>         NA        NA FALSE
#> 4 141607615 MGAM  141607613 141806547 TRUE 
#> 5 164000000 <NA>         NA        NA FALSE
#> 6 118528028 TREH  118528026 118550359 TRUE
nkhmeac6

nkhmeac62#

我们可以使用sapply遍历genes_of_interest中的所有列,并将jap中显示的位置与间隔进行比较。然后用另一个apply Package 它,以确定行的any是否为TRUE。或者我们可以将外部apply替换为as.logical(rowSums()),两个函数的输出相同。
请注意,between函数来自dplyr包。

library(dplyr)

apply(sapply(1:ncol(genes_of_interest), \(x) between(jap$POS, genes_of_interest[1, x], genes_of_interest[2, x])), 1, any)

# or 

as.logical(rowSums(sapply(1:ncol(genes_of_interest), \(x) between(jap$POS, genes_of_interest[1, x], genes_of_interest[2, x]))))

输出

[1] FALSE FALSE FALSE  TRUE FALSE  TRUE
juud5qan

juud5qan3#

使用矩阵:

a <- matrix(jap$POS, nrow(df), ncol(df2))
b <- t(genes_of_interest)
low <- matrix(b[,1], nrow(df), ncol(df2), byrow = TRUE)
up <- matrix(b[,2], nrow(df), ncol(df2), byrow = TRUE)
rowSums(a > low & a < up)>0
[1] FALSE FALSE FALSE  TRUE FALSE  TRUE

相关问题