我目前正在处理一个大型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解决方案也很受欢迎,但由于我的表有数百万行,效率也相当重要
谢谢,
答案 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
是每个组中的行数(按ref1
和ref2
分组)。
答案 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)