向下移动一行,删除最后一行的值n行

问题描述:

我已经阅读了shift和seq的说明,但是不能自己弄清楚这一行。 我需要一次向下移动一列数字,每次移动3行,消除最后一个值。 所以,如果我有:向下移动一行,删除最后一行的值n行

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 

我有大约30万行。

+0

为什么在期望的输出中有新的行吗?实际上是否应该由代码添加? –

+0

不,对不起,不应再添加行。 – oceanfront

使用set从data.table你可以消除所有的第三行:

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 
+0

for循环是不必要的imo。您可以使用该序列将数据分配到“i”中,并一次性更改所有相应的val2值。 –

+0

我没有使用for循环,但使用了测试[seq(1,NROW(test),by = 3)]] oceanfront

这里是另一种解决方案(与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 
+0

我试过这个,但得到了一个data.table错误,它不允许我使用:=,因为我不是一个程序员,这对我来说太难以纠正。 – oceanfront

基础R

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