klaus-0
klaus-0

Reputation: 15

Creating a new column using the previous value of a different column and the previous value of itself

how can I create a new column which starting value is 1 and the following values are a multiplication of the previous value of a column (b) and the previous value of itself (d)?

these data are only made up, but have the structure of my data:

> a <- rep(1:10, 3)
> b <- runif(30)
> c <- tibble(a,b)
> c
# A tibble: 30 x 2
       a     b
   <int> <dbl>
 1     1 0.945
 2     2 0.280
 3     3 0.464
 4     4 0.245
 5     5 0.917
 6     6 0.913
 7     7 0.144
 8     8 0.481
 9     9 0.873
10    10 0.754
# ... with 20 more rows

Then I try to calculate column d:

> c <- c %>%
+   group_by(a) %>%
+   mutate(d = accumulate(lag(b, k = 1), `*`, .init = 1))

and it should look like this

# A tibble: 30 x 3
# Groups:   a [10]
       a     b      d
   <int> <dbl>  <dbl>
 1     1 0.945  1    <--- b[1] * d[1] = d[2]
 2     2 0.280  0.945
 3     3 0.464  0.265
 4     4 0.245  0.123
 5     5 0.917  0.03 
#...

But instead I am getting this error message.

Fehler: Column `d` must be length 3 (the group size) or one, not 4

Upvotes: 0

Views: 80

Answers (2)

Ian Campbell
Ian Campbell

Reputation: 24888

The problem is that when you initialize accumulate with .init = that adds an extra first element of the vector.

You could try this:

library(dplyr)
library(purrr)

 c %>%
   group_by(a) %>%
   mutate(d = accumulate(b[(2:length(b))-1], `*`,.init=1)) %>% 
   arrange(a)
#       a     b      d
#   <int> <dbl>  <dbl>
# 1     1 0.266 1     
# 2     1 0.206 0.266 
# 3     1 0.935 0.0547
# 4     2 0.372 1     
# 5     2 0.177 0.372 
# … with 25 more rows

Data

library(tibble)
set.seed(1)
 a <- rep(1:10, 3)
 b <- runif(30)
 c <- tibble(a,b)

Upvotes: 1

Jrm_FRL
Jrm_FRL

Reputation: 1433

Using dplyr, I would do this:

c %>% 
  mutate(d = 1*accumulate(.x = b[-length(b)], 
                         .init = 1,
                         .f = `*`))

# # A tibble: 30 x 3
# a      b        d
# <int>  <dbl>    <dbl>
#   1     1 0.562  1       
# 2     2 0.668  0.562   
# 3     3 0.100  0.375   
# 4     4 0.242  0.0376  
# 5     5 0.0646 0.00907 
# 6     6 0.373  0.000586
# 7     7 0.664  0.000219
# 8     8 0.915  0.000145
# 9     9 0.848  0.000133
# 10    10 0.952  0.000113
# # ... with 20 more rows

Upvotes: 0

Related Questions