在R中,如何使用滑动窗口计算位置然后进行过滤?

问题描述 投票:0回答:1

滑动窗口已经有几个问题,例如herethere,但我不明白我的情况。我有一个带有

positions
列的数据框。我想使用 100 的浮动窗口并识别包含至少 3 个区间内位置值的所有窗口。我的实际数据集很长,但让我们使用以下可重现的示例:

set.seed(0)
possible_values <- c("A", "B", "C", "D")
col1 <- sample(possible_values, 17, replace = TRUE)
positions <- c(5,17,57,101,105,123,400,578,698,707,717,735,787,811,832,853,919)
df <- data.frame(col1, positions) 
> df
   col1 positions
1     B         5
2     A        17
3     D        57
4     D       101
5     B       105
6     B       123
7     D       400
8     C       578
9     D       698
10    C       707
11    D       717
12    A       735
13    B       787
14    A       811
15    C       832
16    B       853
17    A       919

我想在仓位列上使用间隔为 100 的滑动窗口,并报告哪个窗口包含 3 次或更多出现的仓位,以及窗口的起始值。最好使用 tidyverse。 预期结果是:

col2 <- c(5,17,57,101,707,717,735,787)
count <- c(5,4,4,3,4,4,4,4)
expected <- data.frame(col2,count)
> expected
  col2 count
1    5     5
2   17     4
3   57     4
4  101     3
5  707     4
6  717     4
7  735     4
8  787     4

我尝试了不同的代码,例如这个,但没有达到预期的结果:

> df_window_counts <- df %>% arrange(positions) %>%
     mutate(window_start = findInterval(positions, seq(min(positions), max(positions), 
        by = window_size))) %>%
     group_by(window_start) %>%
     summarise(count = sum(!is.na(positions))) %>%
     filter(count >= 3)
> df_window_counts
# A tibble: 3 × 2
  window_start count
         <int> <int>
1            1     4
2            8     4
3            9     3

我也尝试过使用滑块包,但我没有成功。任何帮助将不胜感激。

r tidyverse
1个回答
0
投票

我认为(还)没有用于滑动窗口的 tidyverse 函数(尽管也许很快)。这并不“容易”。

一些建议:

应用窗口

df %>%
  mutate(
    count = sapply(positions,
       function(pos) sum(between(positions, pos, pos+100)))
  )
#    col1 positions count
# 1     B         5     5
# 2     A        17     4
# 3     D        57     4
# 4     C       101     3
# 5     A       105     2
# 6     B       123     1
# 7     A       400     1
# 8     C       578     1
# 9     C       698     5
# 10    B       707     4
# 11    B       717     4
# 12    C       735     4
# 13    C       787     4
# 14    A       811     3
# 15    A       832     3
# 16    A       853     2
# 17    B       919     1

范围连接

df %>%
  mutate(rn = row_number(), rhs = positions + 100) %>%
  left_join(df, join_by(between(y$positions, x$positions, x$rhs)), suffix = c("", ".y")) %>%
  summarize(.by = c(rn, col1, positions), n = n()) %>%
  select(-rn)
#    col1 positions n
# 1     B         5 5
# 2     A        17 4
# 3     D        57 4
# 4     C       101 3
# 5     A       105 2
# 6     B       123 1
# 7     A       400 1
# 8     C       578 1
# 9     C       698 5
# 10    B       707 4
# 11    B       717 4
# 12    C       735 4
# 13    C       787 4
# 14    A       811 3
# 15    A       832 3
# 16    A       853 2
# 17    B       919 1
© www.soinside.com 2019 - 2024. All rights reserved.