2013-12-18 2 views
3

У меня есть данные в виде data.table приведенного нижеКомплексный алгоритма в R с использованием data.tables предыдущих строк значения

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 = <pointer: 0x0000000000320788>) 

мне нужно, чтобы сформировать 4 новых столбцы csi_begin, csi_end, IRQ и csi_order , значение csi_begin и csi_end, когда atp = 1 напрямую зависит от значений inv и gu.

Но когда АТП не равен 1 csi_begin и csi_end зависит от INV и гу значений и значение IRQ из предыдущего ряда Значение IRQ зависит от csi_order этой строки, если АТП == 1 еще 0 и его значение зависит csi_order в двух строках предыдущего значения csi_begin.

Я написал условие с помощью цикла for. Ниже приведен код, указанный

lostsales<-function(transit) 
{ 

if (transit$atp==1) 
{ 
    transit$csi_begin[i]<-(transit$inv)[i] 
    transit$csi_end[i]<-transit$csi_begin[i]-transit$GU[i] 
} 
else 
{ 
    transit$csi_begin[i]<-(transit$inv)[i]+transit$IRQ[i-1] 
    transit$csi_end[i]<-transit$csi_begin[i]-transit$GU[i] 
} 
if (transit$csi_begin[i-2]!= NA) 
{ 
    transit$csi_order[i]<-transit$csi_begin[i-2] 
} 
else 
    { transit$csi_order[i]<-0} 
if (transit$atp==1) 
{ 
    transit$IRQ[i]<-transit$csi_order[i]-transit$RUTL[i] 
} 

else 
{ 
    transit$IRQ[i]<-0 
} 
} 

Может кто-нибудь помочь мне, как сделать эффективный цикл с использованием data.tables setkeys? Поскольку мой набор данных очень велик, и я не могу использовать для цикла иначе, время будет очень высоким.

+0

У вас нет столбца с именем 'IRQ' в ваших данных, но он отображается в вашем примере/ –

+0

Поскольку IRQ формируется по значению CSi_order else 0, когда atp! = 1 – user2786962

+0

ОК, это имеет смысл, но посмотрите на свою сначала 'else'. Вы ссылаетесь на 'транзит $ IRQ', не создавая его ранее (' транзит $ csi_begin [i] <- (транзит $ inv) [i] + транзит $ IRQ [i-1] '). Поэтому я не вижу, как это может работать так, как написано. –

ответ

1

Добавление желаемого результата в ваш пример будет очень полезным, так как у меня возникают проблемы с логикой if/then. Но я все равно нанёс удар:

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 = "<pointer: 0x0000000000320788>") 

# 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 

Этот результат близок к тому, что вы ожидали?

Смежные вопросы