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
是每组的行数(按ref1
和ref2
分组)。
以上使用 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)
我目前正在使用一个大型 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
是每组的行数(按ref1
和ref2
分组)。
以上使用 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)