向下移动一行,删除最后一行的值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万行。
使用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
for循环是不必要的imo。您可以使用该序列将数据分配到“i”中,并一次性更改所有相应的val2值。 –
我没有使用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
我试过这个,但得到了一个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
为什么在期望的输出中有新的行吗?实际上是否应该由代码添加? –
不,对不起,不应再添加行。 – oceanfront