如何检查向量是否为 LIFO/FIFO 递减 [英] How to check whether a vector is LIFO/FIFO decreasing

查看:35
本文介绍了如何检查向量是否为 LIFO/FIFO 递减的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个 data.table,其中每一行包含两个向量:

Suppose I have a data.table where each row consists of two vectors:

  1. 预减法"向量.
  2. 减法后"向量.

前减法是最左半列,后减法是最右列,末尾有后缀prm".

The pre-subtraction is the left-half most column and the post- is the right-most columns, with the suffix "prm" at the end.

例如:

#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

一个后进先出向量必须在影响更左的元素之前按元素向右递减.第一行 VIOLATES LIFO 因为

A LIFO vector must decrease element-wise to the right before affecting more-left elements. The first row VIOLATES LIFO because

(2, 9, 0) -->(0, 9, 0) 应该已经从最左边单元的 2 之前的 9 中减去了 2.

(2, 9, 0) --> (0, 9, 0) should have subtracted the 2 from the 9 before the 2 on the left-most unit.

我想进行子集化以仅包含具有prm"列的行作为非 prm 列的 LIFO 减法.例如

I would like to subset to include ONLY the rows that have the 'prm' columns as LIFO subtractions of the non prm columns. E.g.

   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(先进先出)是优先考虑某些元素的减法方式.

LIFO (last-in-first-out) and FIFO (first-in-first-out) are ways of subtraction that prioritize certain elements.

考虑一个数字向量 (a,b,c).认为c"是最近的,a"是最近的.

Consider a vector of numbers, (a,b,c). Consider "c" to be the most recent and "a" to be the least recent.

这个向量中的单元总数是a+b+c.

The total number of units in this vector is a+b+c.

如果我们从中减去 d 个单位,在 LIFO 或 FIFO 减法下,我们不会从每个元素中减去 d,而是从最近的 (LIFO) 或最近的 (FIFO) 中逐个元素地减去它,直到它被耗尽(最小值为 0).

If we subtract d units from it, under LIFO or FIFO subtraction, we do not subtract d from every element, rather, we subtract it elementwise from the most recent (LIFO) or least recent (FIFO), until it is depleted (with a min of 0).

例如

LIFO: (3,2,1) - 5 = (3,2,1 - 5) --> (3,2 -4 ,0) --> (3 -2 ,0,0) --> (1,0,0)

LIFO: (3,2,1) - 5 = (3,2,1 - 5) --> (3,2 -4 ,0) --> (3 -2 ,0,0) --> (1,0,0)

先进先出:(3,2,1) - 5 = (3-5,2,1) --> (0,2 -2 ,1) --> (0,0,1)

FIFO: (3,2,1) - 5 = (3-5,2,1) --> (0,2 -2 ,1) --> (0 ,0,1)

推荐答案

这是一种可能的方法,可以在过滤具有 lifo 向量的行之前先计算 lifo 向量:

Here is a possible approach to calculate the lifo vector first before filter for those rows with lifo vectors:

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

这篇关于如何检查向量是否为 LIFO/FIFO 递减的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆