带有seq的na.locf在R中的大列中

时间:2017-09-12 11:02:43

标签: r data.table zoo

我目前正在处理一个大型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,所以我假设我想使用动物园包中的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

e.g。像

这样的东西
df$dist <- na.locf(df$dist, by = 2)

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

谢谢,

4 个答案:

答案 0 :(得分:5)

我会尝试以下方法:

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分组)。

答案 1 :(得分:1)

使用dplyr进行上述实现

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

尽管不需要分组,但有点慢,但这也有效:

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