Complex algorithm in R with data.tables using previous rows values

前端 未结 1 1826
温柔的废话
温柔的废话 2021-01-20 06:30

I have my data in the form of a data.table given below

structure(list(atp = c(1, 0, 1, 0, 0, 1), len = c(2, NA, 3, NA, 
NA, 1), inv = c(593, 823, 668, 640, 5         


        
1条回答
  •  孤街浪徒
    2021-01-20 07:03

    Adding the desired outcome to your example would be very helpful, as I'm having trouble following the if/then logic. But I took a stab at it anyway:

    library(data.table)
    
    # Example data:
    dt <- structure(list(atp = c(1, 0, 1, 0, 0, 1), len = c(2, NA, 3, NA, NA, 1), inv = c(593, 823, 668, 640, 593, 745), GU = c(36, 94, 57, 105, 48, 67), RUTL = c(100, NA, 173, NA, NA, 7)), .Names = c("atp", "len", "inv", "GU", "RUTL"), row.names = c(NA, -6L), class = c("data.table", "data.frame"), .internal.selfref = "")
    
    # Add a row number:
    dt[,rn:=.I]
    
    # Use this function to get the value from a previous (shiftLen is negative) or future (shiftLen is positive) row:
    rowShift <- function(x, shiftLen = 1L) {
      r <- (1L + shiftLen):(length(x) + shiftLen)
      r[r<1] <- NA
      return(x[r])
    }
    
    # My attempt to follow the seemingly circular if/then rules:
    lostsales2 <- function(transit) {
      # If atp==1, set csi_begin to inv and csi_end to csi_begin - GU:
      transit[atp==1, `:=`(csi_begin=inv, csi_end=inv-GU)]
    
      # Set csi_order to the value of csi_begin from two rows prior:
      transit[, csi_order:=rowShift(csi_begin,-2)]
    
      # Set csi_order to 0 if csi_begin from two rows prior was NA
      transit[is.na(csi_order), csi_order:=0]
    
      # Initialize IRQ to 0
      transit[, IRQ:=0]
    
      # If ATP==1, set IRQ to csi_order - RUTL
      transit[atp==1, IRQ:=csi_order-RUTL]
    
      # If ATP!=1, set csi_begin to inv + IRQ value from previous row, and csi_end to csi_begin - GU
      transit[atp!=1, `:=`(csi_begin=inv+rowShift(IRQ,-1), csi_end=inv+rowShift(IRQ,-1)-GU)]
      return(transit)
    }
    
    lostsales2(dt)
    ##    atp len inv  GU RUTL rn csi_begin csi_end csi_order  IRQ
    ## 1:   1   2 593  36  100  1       593     557         0 -100
    ## 2:   0  NA 823  94   NA  2        NA      NA         0    0
    ## 3:   1   3 668  57  173  3       668     611       593  420
    ## 4:   0  NA 640 105   NA  4       640     535         0    0
    ## 5:   0  NA 593  48   NA  5       593     545       668    0
    ## 6:   1   1 745  67    7  6       745     678       640  633
    

    Is this output close to what you were expecting?

    0 讨论(0)
提交回复
热议问题