向下移动一行,一次删除 n 行的最后一个值
Shift a row down removing last value n rows at a time
我已经阅读了 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
我有大约 30 万行。
使用 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
这是另一个解决方案(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
基础 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
我已经阅读了 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
我有大约 30 万行。
使用 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
这是另一个解决方案(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
基础 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