我已经阅读了shift和seq的说明,但我自己无法想出这个。 我需要向下移动一列数字,一次3行,消除最后一个值。 如果我有:
serial val1
1 6
2 8
3 7
4 11
5 9
6 3
我需要的输出是:
serial val1 val2
1 6 NULL
2 8 6
3 7 8
4 11 NULL
5 9 11
6 3 9
我有大约300k行。
答案 0 :(得分:2)
使用data.table中的set
,您可以消除每第3行:
test <- data.table(serial = c(1, 2, 3, 4, 5, 6, 7), val1 = c(6, 8, 7, 11, 9, 3, 4))
test[, val2 := shift(val1)]
for (i in seq(1, nrow(test), 3)){
set(test, i = i, j = 3, value = NA)
}
serial val1 val2
1: 1 6 NA
2: 2 8 6
3: 3 7 8
4: 4 11 NA
5: 5 9 11
6: 6 3 9
7: 7 4 NA
答案 1 :(得分:2)
这是另一种解决方案(使用gl()
):
library("data.table")
df <- data.table(serial = c(1, 2, 3, 4, 5, 6, 7), val1 = c(6, 8, 7, 11, 9, 3, 4))
n <- df[, .N]
df[, f:=gl(n, 3, length=n)]
df[, val2 := shift(val1), by = f]
# > df
# serial val1 f val2
# 1: 1 6 1 NA
# 2: 2 8 1 6
# 3: 3 7 1 8
# 4: 4 11 2 NA
# 5: 5 9 2 11
# 6: 6 3 2 9
# 7: 7 4 3 NA
答案 2 :(得分:0)
d1 = data.frame(serial=1:6, val1=c(6,8,7,11,9,3))
#' Return new vector with values of each len in v shifted one index
#' It is an error if v modulo len is =! 0
shiftnew = function(v, len, simpl=T) {
stopifnot(length(v) %% len == 0)
ind = as.factor(rep(1:(length(v)/len), each=len))
newv <- tapply(v, ind, function(chunk){
shifted <- c(NA, chunk[1:(len-1)])
})
if(simpl) unlist(newv)
}
d1$val2 <- shiftnew(d1[, "val1"], 3)
#output
serial val1 val2
1 1 6 NA
2 2 8 6
3 3 7 8
4 4 11 NA
5 5 9 11
6 6 3 9