r - 给定名称范围对的向量化子集

标签 r dplyr tidyverse

考虑两个小标题datakey,如下所示:

library(tidyverse) # v1.3.2
set.seed(123)

data <- tibble(id = rep(LETTERS[1:10], each = 10),
               position = rep(1:10, 10),
               zip = sample(letters, 100, replace = T),
               zap = sample(letters, 100, replace = T),
               zop = sample(letters, 100, replace = T))

# A tibble: 100 × 5
   id    position zip   zap   zop  
   <chr>    <int> <chr> <chr> <chr>
 1 A            1 l     n     u    
 2 A            2 y     f     h    
 3 A            3 n     y     u    
 4 A            4 c     h     g    
 5 A            5 n     l     t    
 6 A            6 g     z     r    
 7 A            7 c     d     q    
 8 A            8 w     m     a    
 9 A            9 v     n     b    
10 A           10 z     u     q    
# … with 90 more rows
key <- tibble(id = c("A","D","H"),
              start = c(2, 5, 7),
              end = c(4, 6, 9))

# A tibble: 3 × 3
  id    start   end
  <chr> <dbl> <dbl>
1 A         2     4
2 D         5     6
3 H         7     9

以及所需的输出:

# A tibble: 8 × 5
  id    position zip   zap   zop  
  <chr>    <int> <chr> <chr> <chr>
1 A            2 s     u     w    
2 A            3 n     e     a    
3 A            4 c     h     h    
4 D            5 j     j     w    
5 D            6 m     e     z    
6 H            7 m     v     h    
7 H            8 e     q     w    
8 H            9 v     j     y

通过 idkey 给出的 position 范围对 data 进行子集化的最有效方法是什么?我可以想到两种方法,但都不是很快。

1。 apply()key 行,并绑定(bind)各个部分

apply(X = key, MARGIN = 1, function(x) {
  data |>
    dplyr::filter(id == x[1],
                  position %in% x[2]:x[3])
  }
) |> dplyr::bind_rows()

2。旋转并填充key,然后join()

key |> tidyr::pivot_longer(cols = c(start, end),
                           values_to = "position") |>
       dplyr::select(id, position) |>
       dplyr::group_by(id) |>
       tidyr::complete(position = seq(from = min(position),
                                      to = max(position))) |>
       dplyr::left_join(data)

给定具有数百万行的数据和具有数百行的key,哪种整洁的方法可能是最快的?

最佳答案

我们可以在分组后进行inner_join,然后进行切片

library(dplyr)
inner_join(data, key) %>% 
  group_by(id) %>%
  slice(first(start):first(end)) %>% 
  ungroup %>%
  select(-c(start, end))

-输出

# A tibble: 8 × 5
  id    position zip   zap   zop  
  <chr>    <int> <chr> <chr> <chr>
1 A            2 s     u     w    
2 A            3 n     e     a    
3 A            4 c     h     h    
4 D            5 j     j     w    
5 D            6 m     e     z    
6 H            7 m     v     h    
7 H            8 e     q     w    
8 H            9 v     j     y    

或者另一种选择是在按“id”分组后使用cur_group()来对“key”行进行子集化

data %>%
   filter(id %in% key$id) %>% 
   group_by(id) %>%
   filter(row_number() >= key$start[match(cur_group()$id, key$id)], 
       row_number() <= key$end[match(cur_group()$id, key$id)] ) %>% 
   ungroup

-输出

# A tibble: 8 × 5
  id    position zip   zap   zop  
  <chr>    <int> <chr> <chr> <chr>
1 A            2 s     u     w    
2 A            3 n     e     a    
3 A            4 c     h     h    
4 D            5 j     j     w    
5 D            6 m     e     z    
6 H            7 m     v     h    
7 H            8 e     q     w    
8 H            9 v     j     y  

关于r - 给定名称范围对的向量化子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74437717/

相关文章:

javascript - 如何使 R 中的粘性导航栏 Shiny ?

r - 在 R 和 Sparklyr 中,将表写入 .CSV (spark_write_csv) 会生成许多文件,而不是一个文件。为什么?我可以改变这一点吗?

R:带有粘贴的引用列名称

r - 如何将列传递给arrange()和mutate()

r - 查找在 R 中构成主键的变量组合

r - 是否有更简单的方法在 data.frame 中创建具有 2 个以上级别的因子变量?

r - 在 ggrepel 标签中使用plotmath

r - 使用 igraph 将边缘属性显示为标签

r - 如何在 R 中计算已滚动的股票投资组合的百分比?

R 对 data.frame 中两个变量的惰性求值