子设置行是列表中匹配的+ - N个条目

时间:2011-07-27 14:18:17

标签: r

我有一个具有日期时间列的数据表(dt)。我还有一个单独的日期时间列表(L)。

如何在L的日期时间列中为dt的项目的每个匹配返回+/- N行的dt子集?

我有兴趣尽可能地做这个,所以这个案例是一个日期时间,但我也有兴趣为因子和整数做这个。理想情况下,这也会重复删除任何重叠。

基本上这就像grep 'foo|foo1' -A10 -B10,它转换为“显示匹配foo或foo1的行,包括前后10行”。

2 个答案:

答案 0 :(得分:4)

以示例

dt <- data.frame (dt = 101 : 200)
L <- c (163, 200, 131)

然后你的比赛的行号是

matches <- which (dt$dt %in% L)

现在说你要从之前的3行到1之后:

extrarows <- -3 : 1

现在outer是你的朋友:

rows <- outer(extrarows, matches, `+`)

几乎就是你要找的东西,我们只是

  • 需要确保条目都是有效的行号(rows中可能有负数):

    rows <- rows [rows %in% seq_len (nrow (dt))]

  • 您可能还想摆脱重复:

    rows <- unique (rows)

  • 如果您想保留rows的矩阵结构,可能将无效索引设置为NA比删除它们更好:

    rows [! rows %in% seq_len (nrow (dt))] <- NA

现在你回来了

dt [rows,]

答案 1 :(得分:2)

很难在不查看数据的情况下提供准确的代码,但您可能希望使用%in%来查找匹配项,例如,

match_index <- which(dt$some_column %in% L)

现在,我正在编写数字以显示如何在前后获取行。

match_index <- c(1, 33, 35, 50)
n <- 55        #in practice, this will be nrow(dt)

对于每个匹配,从之前的10个值到之后的10个值获取一系列值,跳过位于数据范围之外的数字。

all_values <- lapply(match_index, function(x) seq.int(max(1, x - 10), min(x + 10, n)))

合并为一个载体。

all_values <- do.call(c, all_values)

删除重复项。

all_values[!duplicated(all_values)]