假设我有一个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]


数据:

> 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


LIFO向量必须在影响左侧元素之前向右逐元素减小。第一行VIOLATES 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


编辑:

LIFO(后进先出)和FIFO(先进先出)是对某些元素进行优先级排序的减法方式。

考虑一个数字向量(a,b,c)。认为“ c”是最新的,“ a”是最新的。

该向量中的单位总数为a + b + c。

如果我们在LIFO或FIFO减法下从中减去d个单位,则不会从每个元素中减去d,而是从最近的(LIFO)或最近的(FIFO)逐元素减去d,直到耗尽为止(最低为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]
    ]


输出:

   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


数据:

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"
        ))

09-04 13:59