Fellow R-Stackoverflowers,
I have a data table with 2 columns and I'm trying to calculate a new third column based on both the 2 existing column values and the new column calculated value for the previous row.
I have been checking the forums and I have tried a couple of answers but I don't get it right. I hope you can help me.
Here is a reproducible example:
error <- c(1,1,0,0,0,1,1,1,1,0)
trigger <- c(FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE)
expected <- c(1,2,0,0,0,1,2,3,4,0)
DTtest <- data.table(error, trigger, expected)
DTtest
error trigger expected
1: 1 FALSE 1
2: 1 TRUE 2
3: 0 FALSE 0
4: 0 FALSE 0
5: 0 FALSE 0
6: 1 FALSE 1
7: 1 TRUE 2
8: 1 TRUE 3
9: 1 TRUE 4
10: 0 FALSE 0
The "expected" column includes the values I expect to calculate with the "error" and "trigger" columns. The formula I would like to apply would be the following:
if(trigger) {
new_column = new_column(previous_row) + 1
} else {
new_column = error
}
My first try was to use an ifelse directly to update the new column. I found that I had to actually initialize the new column for it to run:
DTtest <- DTtest[, impact:=0]
DTtest[, impact:=ifelse(trigger, lag(impact)+1, error)]
This option does calculate the new column "impact" but the results do not match the expected value I got calculating the column in Excel (something I can't do with the whole data table, as it's pretty big):
error trigger expected impact
1: 1 FALSE 1 1
2: 1 TRUE 2 1
3: 0 FALSE 0 0
4: 0 FALSE 0 0
5: 0 FALSE 0 0
6: 1 FALSE 1 1
7: 1 TRUE 2 1
8: 1 TRUE 3 1
9: 1 TRUE 4 1
10: 0 FALSE 0 0
Then I tried a for loop but the results are not correct either:
for(index in nrow(DTtest)){
imp <- 0
if(index==1){
imp <- DTtest[index]$error
} else {
imp <- DTtest[index-1]$impact+1
}
set(DTtest, i=index, j=as.integer(4), value=imp )
}
I have the feeling that lag(impact) does not get the updated value for some reason, but I can't fancy why.
Would you please help me? .
Thank you!
Here is an alternative approach using groups:
DTtest[, grp:=cumsum(!trigger)][,new:=c(error[1], cumsum(head(error, -1))+1),grp][]
error trigger expected grp new
1: 1 FALSE 1 1 1
2: 1 TRUE 2 1 2
3: 0 FALSE 0 2 0
4: 0 FALSE 0 3 0
5: 0 FALSE 0 4 0
6: 1 FALSE 1 5 1
7: 1 TRUE 2 5 2
8: 1 TRUE 3 5 3
9: 1 TRUE 4 5 4
10: 0 FALSE 0 6 0
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments