wol*_*oor 8 queue stack r data.table
假设我有一个data.table,其中每行包含两个向量:
预减法是最左边的列,后变量是最右边的列,末尾是后缀"prm".
例如:
#Sample Data
set.seed(2)
fill = data.table(n=1:7)
Tp=3
for(t in 1:Tp){
set(x = fill, j = paste0('v',t), value = sample(0:10,7))
}
fill[1,paste0('v',3):=0]
fill[5,paste0('v',2):=0]
fill[5,paste0('v',3):=0]
for(t in 1:Tp){
fill[,paste0('v',t,'prm'):=get(paste0('v',t))]
}
fill[1,paste0('v',1,'prm'):=0]
fill[2,paste0('v',2,'prm'):=1]
fill[5,paste0('v',3,'prm'):=1]
fill[7,paste0('v',3,'prm'):=2]
Run Code Online (Sandbox Code Playgroud)
数据:
> fill
n v1 v2 v3 v1prm v2prm v3prm
1: 1 2 9 0 0 9 0
2: 2 7 4 8 7 1 8
3: 3 5 10 9 5 10 9
4: 4 1 8 1 1 8 1
5: 5 6 0 0 6 0 1
6: 6 8 7 0 8 7 0
7: 7 0 0 6 0 0 2
Run Code Online (Sandbox Code Playgroud)
在影响更左边的元素之前,LIFO向量必须在元素方向上减少.第一排违反了LIFO因为
(2, 9, 0) --> (0, 9, 0) 应该从最左边单位的2之前的9减去2.
我想将子集仅包括具有'prm'列的行作为非prm列的LIFO减法.例如
n v1 v2 v3 v1prm v2prm v3prm
1: 3 5 10 9 5 10 9
2: 4 1 8 1 1 8 1
3: 6 8 7 0 8 7 0
4: 7 0 0 6 0 0 2
Run Code Online (Sandbox Code Playgroud)
编辑:
LIFO(后进先出)和FIFO(先进先出)是减法的方法,优先考虑某些元素.
考虑一个数字向量,(a,b,c).认为"c"是最近的,而"a"是最近的.
该向量中的单元总数为a + b + c.
如果我们从它中减去d个单位,在LIFO或FIFO减法下,我们不会从每个元素中减去d,而是从最近的(LIFO)或最近的(FIFO)中逐个减去它,直到它耗尽(使用最小的0).
例如
LIFO:(3,2,1) - 5 =(3,2,1 - 5) - >(3,2 -4,0) - >(3 -2,0,0) - >(1 ,0,0)
FIFO:(3,2,1) - 5 =(3-5,2,1) - >(0,2 -2,1) - >(0,0,1)
下面是一个可能的方法来计算lifo向量,然后在具有lifo向量的那些行的过滤之前:
#convert into long format from MichaelChirico and svenkatesh
tbl <- melt(fill, meas=patterns("^v[1-9]$", "prm$"),
value.name=c("bef","aft"))
setorder(tbl, n, -variable)
#filter for those lifo vector
fill[n %in%
tbl[, {
#calculate stock taken out
dif <- sum(bef) - sum(aft)
#calculate lifo vector
lifo <- pmin(pmax(cumsum(bef) - dif, 0L), bef)
#check if after is this lifo vector
identical(lifo, aft)
}, by=.(n)][(V1), n]
]
Run Code Online (Sandbox Code Playgroud)
输出:
n v1 v2 v3 v1prm v2prm v3prm
1: 3 5 10 9 5 10 9
2: 4 1 8 1 1 8 1
3: 6 8 7 0 8 7 0
4: 7 0 0 6 0 0 2
Run Code Online (Sandbox Code Playgroud)
数据:
library(data.table)
fill <- structure(list(n = 1:7, v1 = c(2L, 7L, 5L, 1L, 6L, 8L, 0L), v2 = c(9L,
4L, 10L, 8L, 0L, 7L, 0L), v3 = c(0L, 8L, 9L, 1L, 0L, 0L, 6L),
v1prm = c(0L, 7L, 5L, 1L, 6L, 8L, 0L), v2prm = c(9L, 1L,
10L, 8L, 0L, 7L, 0L), v3prm = c(0L, 8L, 9L, 1L, 1L, 0L, 2L
)), row.names = c(NA, -7L), class = c("data.table", "data.frame"
))
Run Code Online (Sandbox Code Playgroud)