I have data
library(dplyr, warn.conflicts = FALSE)
mtcars %>%
as_tibble() %>%
select(mpg, qsec) %>%
head(5) %>%
mutate(new_col = c(10, rep(NA, times = nrow(.)-1)))
#> # A tibble: 5 × 3
#> mpg qsec new_col
#> <dbl> <dbl> <dbl>
#> 1 21 16.5 10
#> 2 21 17.0 NA
#> 3 22.8 18.6 NA
#> 4 21.4 19.4 NA
#> 5 18.7 17.0 NA
I need a solution for new_col like mpg + qsec - lag(new_col) but with recursion.
For the second row : 21 + 17.0 - 10 = 28
For the third : 22.8 + 18.6 - 28(from second row) = 13.4
Expected output:
#> # A tibble: 5 × 3
#> mpg qsec new_col
#> <dbl> <dbl> <dbl>
#> 1 21 16.5 10
#> 2 21 17.0 28
#> 3 22.8 18.6 13.4
#> 4 21.4 19.4 27.4
#> 5 18.7 17.0 8.3
You can use purrr::accumulate() (or base::Reduce() if you prefer):
library(dplyr)
library(purrr)
mtcars %>%
as_tibble() %>%
select(mpg, qsec) %>%
head(5) %>%
mutate(new_col = accumulate(tail(mpg + qsec, -1), .f = ~ .y - .x, .init = 10))
# A tibble: 5 × 3
mpg qsec new_col
<dbl> <dbl> <dbl>
1 21 16.5 10
2 21 17.0 28.0
3 22.8 18.6 13.4
4 21.4 19.4 27.4
5 18.7 17.0 8.27
Another possible solution, using purrr::reduce:
library(tidyverse)
df %>%
transmute(reduce(2:n(), ~ {.x$new_col[.y] <- (.x$mpg[.y] + .x$qsec[.y] -
.x$new_col[.y-1]); .x}, .init = .))
#> # A tibble: 5 × 3
#> mpg qsec new_col
#> <dbl> <dbl> <dbl>
#> 1 21 16.5 10
#> 2 21 17.0 28.0
#> 3 22.8 18.6 13.4
#> 4 21.4 19.4 27.4
#> 5 18.7 17.0 8.27
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With