Decremental multiplication in R

Below is a sample data df

, with many variables, where C

is one, the length of a 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 a product C

and a decremental factor by 0.1 .
Multiplication should only be done to count 10

values C_C

from a point where there is a value C

other than 0

. Also the result must be saved from the next data point. If C !=0

is in Id ==2

, then the product should be kept from. ID==3


If the number is less than 10

continuous zeros after a nonzero number will only be reset to a new value C

, and if no further data is found, 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

      

Observing the required result
1. The value in C

, which is not 0

, is enocunter in ID = 2

, therefore the product is kept from ID == 3

ie 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

Thank!

+3


source to share


2 answers


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

      

+3


source


Slightly lengthy procedure sapply

from the R base

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 indices that are not equal to 0 ( vals

), get their corresponding values ​​( df$C[vals]

), and for each value, we multiply it by 1.0, 0.9, 0.8 ... etc, Now that we have everything values

we need, now to place these values

we will generate its corresponding indices ( inds

) using a function seq

. Now we can just assign values

at their respective indices ( inds

) and assign 0 to the remaining values.

+2


source







All Articles