0
votes

I have simple data.table as follows

structure(list(A = c(4L, 4L, 4L, 4L, 4L, 4L, 4L, 2L, 2L, 2L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 1L, 1L, 1L, 1L, 1L), 
    B = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0)), class = c("data.table", "data.frame"), row.names = c(NA, 
-41L), .internal.selfref = <pointer: 0x561c95850b70>)

which looks like -

   A  B
 1: 4  0
 2: 4  0
 3: 4  0
 4: 4  0
 5: 4  0
 6: 4  0
 7: 4  0
 8: 2  0
 9: 2  0
10: 2  0
11: 1  0
12: 1  0
13: 1 -1
14: 1  0
15: 1  0
16: 1  0
17: 1  0
18: 1  0
19: 1  0
20: 1  0
21: 1  0
22: 1  0
23: 1  0
24: 1  0
25: 1  0
26: 1  0
27: 1  0
28: 1  0
29: 1  0
30: 3  0
31: 3  0
32: 3  0
33: 3  0
34: 3  0
35: 4  0
36: 4  0
37: 1  0
38: 1  0
39: 1  0
40: 1  0
41: 1  0

In column A, I want to replace the values of the entire group with values 1 to 6 only when any value in column B is not 0.

Here is the desired outcome -

   A  B
 1: 4  0
 2: 4  0
 3: 4  0
 4: 4  0
 5: 4  0
 6: 4  0
 7: 4  0
 8: 2  0
 9: 2  0
10: 2  0
11: 6  0
12: 6  0
13: 6 -1
14: 6  0
15: 6  0
16: 6  0
17: 6  0
18: 6  0
19: 6  0
20: 6  0
21: 6  0
22: 6  0
23: 6  0
24: 6  0
25: 6  0
26: 6  0
27: 6  0
28: 6  0
29: 6  0
30: 3  0
31: 3  0
32: 3  0
33: 3  0
34: 3  0
35: 4  0
36: 4  0
37: 1  0
38: 1  0
39: 1  0
40: 1  0
41: 1  0

I have tried many ways to solve this problem by using data.table but nothing seems to work. Following just changes values of all groups of 1's, which is incorrect.

t[, A := ifelse(any(B != 0 & A == 1), 6, A), by = A]

There should be an easy and neat way to do this in one line using data.table

Thanks in advance

1

1 Answers

1
votes

Here's an approach with rleid:

data[,.(A = fifelse(rep(any(B!=0),.N) & A == 1, 6 , A), B), by = rleid(A)][,.(A,B)]