R - 标识标志前后的 -n 行*按组*

R - Identify -n rows before and after a flag *by group*

我很难按组

隔离标志前后的 n 行

我在其他地方找到了一个可行的答案,但被行范围小于的组拒绝了。例如,如果范围是 6 行,但一组只有五个观察值,则查询将开始包括来自先前组的不相关观察值。

这里有一些要重现的虚拟数据。

x <- c("", "", "", "1", "", "","", "", "", "", "", "1","", "", "", "", "1", "")
y <- c("2", "6", "4", "4", "7", "9","1", "15", "7", "4", "5", "8","6", "1", "2", "4", "6", "16")
z <- c("a", "a", "a", "a", "a", "a","a", "b", "b", "b", "b", "b","b", "b", "c", "c", "c", "c")

a <- as.data.frame(cbind(x, y, z))

  x  y z
1     2 a
2     6 a
3     4 a
4  1  4 a
5     7 a
6     9 a
7     1 a
8    15 b
9     7 b
10    4 b
11    5 b
12 1  8 b
13    6 b
14    1 b
15    2 c
16    4 c
17 1  6 c
18   16 c

理想情况下,我希望 a 看起来像这样:

  x  y z
1     6 a
2     4 a
3  1  4 a
4     7 a
5     9 a
6     1 a
7     4 b
8     5 b
9  1  8 b
10    6 b
11    1 b
12    2 c
13    4 c
14 1  6 c
15   16 c
a[zoo::rollapply(a$x, 5, function(z) "1" %in% z, partial = TRUE),]
#    x  y z
# 2     6 a
# 3     4 a
# 4  1  4 a
# 5     7 a
# 6     9 a
# 10    4 b
# 11    5 b
# 12 1  8 b
# 13    6 b
# 14    1 b
# 15    2 c
# 16    4 c
# 17 1  6 c
# 18   16 c

zoo::rollapply 一次对“windows” 个数字进行运算。在这里,它是五个,这意味着它查看五个值和 returns 一个值;然后移动一个(四个相同,再加一个),并且 returns 一个值;等等

因为我指定了partial=TRUE(当你需要输出长度与输入长度相同时是必需的),查看的值的长度可能与kernel不一样宽度 (5).

要点是,如果我一次查看五个,如果其中一个是 "1",那么我们就在 "1 的 2 行之内,并且应该被保留。

window 的重要 属性 是 alignment,默认为中心。它定义了结果在 window 中的位置。

在这种情况下,windows 看起来像:

#  [1] ""  ""  ""  "1" ""  ""  ""  ""  ""  ""  ""  "1" ""  ""  ""  ""  "1" "" 
1:     nn-------' (partial match)
2:     ----yy--------' (partial)
3:     `-------yy-------'  there is a window in this set of five, so a true ("yy")
4:         `-------yy-------'
5:             `-------yy-------'
6:                 `-------yy-------'
7:                     `-------nn-------' no "1", so a false
... etc
#  [1] ""  ""  ""  "1" ""  ""  ""  ""  ""  ""  ""  "1" ""  ""  ""  ""  "1" "" 

你可以在前七个 windows 中看到第一个被丢弃(没有一个 "1" 足够接近),我们有五个正确的("yy" 在我的命名法中) , 然后我们得到一个错误的 ("nn") 因为它没有看到 "1".