3
votes

Below is my sample dataframe df, with many variables where C is one among them, the length of the column in a variable.

 ID C
 1  0
 2  1.47349678
 3  0
 4  0
 5  0
 6  0
 7  0
 8  0
 9  0
10  0
11  0
12  0
13  0
14  0
16  1.987
17  0
18  0
19  0
20  0
21  0
22  0
23  0
24  0
25  0
26  0
27  0

I need to create another variable C_C where it consists of product of Cand a decremental factor by 0.1.
The multiplication has to be done only for the count of 10 values of C_C from the point where there is a value of Cother than 0. Also the result has to be stored from the next data point. i.e If C !=0 is found at Id ==2 then the product must be stored from ID==3
If there are less than 10 continuous zeroes after a non zero number would the count just reset to the new value of C, and if there is no further data found the multiplication will stop.

Expected Result

   ID   C              C_C
   1    0              0
   2    1.47349678     0
   3    0              1.47349678
   4    0              1.326147102
   5    0              1.178797424
   6    0              1.031447746
   7    0              0.884098068
   8    0              0.73674839
   9    0              0.589398712
  10    0              0.442049034
  11    0              0.294699356
  12    0              0.147349678
  13    0              0
  14    0              0
  16    1.987          0
  17    0              1.987
  18    0              1.7883
  19    0              1.5896
  20    0              1.3909
  21    0              1.1922
  22    0              0.9935
  23    0              0.7948
  24    0              0.5961
  25    0              0.3974
  26    0              0.1987
  27    0               0

Observation from the Required Result
1. Value in C which is not 0is enocunter at ID = 2, so the product is being stored from ID == 3 i.e C_C3.
2. C_C3 == C2 * 1, C_C4 == C2*0.9, C_C5 == C2 * 0.8......C_C12 == C*0.1, C_C13 == C2 *0.
3. Similarly C_C17 == C16 * 1, C_C18 == C16*0.9, C_C19 == C16 *0.8, .... C_C26 == C16 *0.1, C_C27 == C16*0

Thanks!

2
If there are less than 10 continuous zeroes after a non zero number would the count just reset ? - Ronak Shah
@RonakShah Yeah, I I forgot to mention that. The count should reset new value of C for multiplication. - Tareva

2 Answers

3
votes

With dplyr:

library(dplyr)   
df$group = cumsum(dt$C>0)
df = df %>% group_by(group) %>% mutate(value=sum(C)) %>%
  mutate(n=1.1-0.1*(row_number()-1)) %>% mutate(n=ifelse(n<0|value==0|n==1.1,0,n)) %>%
  mutate(C_C = n*value) %>% ungroup() %>% select(-n,-group,-value) %>% as.data.frame()

   ID     C    C_C
1   1 0.000 0.0000
2   2 1.473 0.0000
3   3 0.000 1.4735
4   4 0.000 1.3261
5   5 0.000 1.1788
6   6 0.000 1.0314
7   7 0.000 0.8841
8   8 0.000 0.7367
9   9 0.000 0.5894
10 10 0.000 0.4420
11 11 0.000 0.2947
12 12 0.000 0.1473
13 13 0.000 0.0000
14 14 0.000 0.0000
15 16 1.987 0.0000
16 17 0.000 1.9870
17 18 0.000 1.7883
18 19 0.000 1.5896
19 20 0.000 1.3909
20 21 0.000 1.1922
21 22 0.000 0.9935
22 23 0.000 0.7948
23 24 0.000 0.5961
24 25 0.000 0.3974
25 26 0.000 0.1987
26 27 0.000 0.0000
2
votes

A little lengthy procedure with sapply from base R

vals <- which(df$C != 0)
values <- c(sapply(df$C[vals], function(x) x * rev(seq(0.1, 1.0, 0.1))))
inds <- c(sapply(vals + 1, function(x) seq(x, x+9)))
df$C_C <- 0
df$C_C[inds] <- values
df$C_C

# [1] 0.0000000 0.0000000 1.4734968 1.3261471 1.1787974 1.0314477 0.8840981
# [8] 0.7367484 0.5893987 0.4420490 0.2946994 0.1473497 0.0000000 0.0000000
#[15] 0.0000000 1.9870000 1.7883000 1.5896000 1.3909000 1.1922000 0.9935000
#[22] 0.7948000 0.5961000 0.3974000 0.1987000 0.0000000

Here, we first find out indices which are not equal to 0 (vals), get their respective values (df$C[vals]) and for each value we multiply it by 1.0, 0.9, 0.8.....etc. We now have all the values which we need , now to place these values we generate its respective indices (inds) using seq function. We can now just assign the values at their respective indices (inds) and assign 0 to remaining values.