na.locf 在 R 中的大列中使用 seq

na.locf with seq in large column in R

我目前正在使用一个大型 data.table,它具有基于 2 个参考列的某些组,然后有一个距离列,该列为每个组中的第一行定义,然后每个跳转 2 个单位时间.

做一个非常小的可重现的例子,我有:

reference1 <- c("ref1", "ref1", "ref1", "ref2", "ref2", "ref2", "ref2", "ref3", "ref3", "ref3")
reference2 <- c("fer1", "fer1", "fer1", "fer1", "fer1", "fer1", "fer1", "fer2", "fer2", "fer2")
firstdist <- c(2, NA, NA, 5, NA, NA, NA, 8, NA, NA)
 df <- data.frame(ref1 = reference1,
                  ref2 = reference2,
                  dist = firstdist)

等于

   ref1 ref2 dist
1  ref1 fer1    2
2  ref1 fer1   NA
3  ref1 fer1   NA
4  ref2 fer1    5
5  ref2 fer1   NA
6  ref2 fer1   NA
7  ref2 fer1   NA
8  ref3 fer2    8
9  ref3 fer2   NA
10 ref3 fer2   NA

我想填写最后一次观察的列并将其向前推进 +2,所以我假设我想为此使用 zoo 包中的 na.locf。四处搜索,我还没有找到任何方法可以在添加常量整数的同时进行。

我想要的输出示例:

   ref1 ref2 dist
1  ref1 fer1    2
2  ref1 fer1    4
3  ref1 fer1    6
4  ref2 fer1    5
5  ref2 fer1    7
6  ref2 fer1    9
7  ref2 fer1   11
8  ref3 fer2    8
9  ref3 fer2   10
10 ref3 fer2   12

例如像

df$dist <- na.locf(df$dist, by = 2)

不是 100% 确定 na.locf 是最好的方法,所以 data.table 解决方案也欢迎,但由于我的 table 有数百万行,效率也相当重要

谢谢,

我会尝试以下方法:

library(data.table)
setDT(df)

df[, dist := seq(first(dist), by = 2, length.out = .N), by = .(ref1, ref2)]

# > df
#     ref1 ref2 dist
#  1: ref1 fer1    2
#  2: ref1 fer1    4
#  3: ref1 fer1    6
#  4: ref2 fer1    5
#  5: ref2 fer1    7
#  6: ref2 fer1    9
#  7: ref2 fer1   11
#  8: ref3 fer2    8
#  9: ref3 fer2   10
# 10: ref3 fer2   12

这里,.N是每组的行数(按ref1ref2分组)。

以上使用 dplyr 的实现

library(dplyr)
df = df %>% group_by(ref1,ref2) %>% 
            mutate(dist = seq(first(dist),by = 2, length.out = n()))

base R 选项将与 ave

df$dist <- with(df, ave(dist, ref1, ref2, FUN = function(x) x[1] + (seq_along(x)-1)*2))
df$dist
#[1]  2  4  6  5  7  9 11  8 10 12

虽然不需要分组,但速度有点慢,但这也有效:

df$dist = Reduce(function(a, b) if (is.na(b)) a + 2 else b, df$dist, accumulate=TRUE)