Изменять новый столбец на основе задержанных значений в этом столбце - подход dplyr - PullRequest
2 голосов
/ 05 марта 2020

Базовый подход и dplyr были подробно описаны здесь Как создать столбец, который использует свое собственное значение задержки, используя dplyr

Я хочу, чтобы первая строка равнялась k, а затем каждая последующая строка быть "c" плюс "a" минус "b".

Базовый подход работает.

Но подход dplyr не дает того же результата, что и базовый подход , См .:

library(tidyverse)
k <- 10 # Set a k value
df1 <- tribble(
  ~a, ~b,
  1,  1,
  1,  2,
  1,  3,
  1,  4,
  1,  5,)
# Base approach
df1$c <- df1$a - df1$b
df1[1, "c"] <- k
df1$c <- cumsum(df1$c)
df1
#> # A tibble: 5 x 3
#>       a     b     c
#>   <dbl> <dbl> <dbl>
#> 1     1     1    10
#> 2     1     2     9
#> 3     1     3     7
#> 4     1     4     4
#> 5     1     5     0
# New df
df2 <- tribble(
  ~a, ~b,
  1,  1,
  1,  2,
  1,  3,
  1,  4,
  1,  5,)
# dplyr approach
df2 %>% 
  mutate(c = lag(cumsum(a - b), 
                 default = k))
#> # A tibble: 5 x 3
#>       a     b     c
#>   <dbl> <dbl> <dbl>
#> 1     1     1    10
#> 2     1     2     0
#> 3     1     3    -1
#> 4     1     4    -3
#> 5     1     5    -6
# Gives two different dataframes

Создано в 2020-03-05 пакетом Представить (v0.3.0)

Альтернативный код и желаемый выход :

library(tidyverse)
# Desired output
tribble(
  ~a, ~b, ~c,
  1, 1, 10,
  1, 2, 9,
  1, 3, 7,
  1, 4, 4,
  1, 5, 0)
#> # A tibble: 5 x 3
#>       a     b     c
#>   <dbl> <dbl> <dbl>
#> 1     1     1    10
#> 2     1     2     9
#> 3     1     3     7
#> 4     1     4     4
#> 5     1     5     0
df2 <- tribble(
  ~a, ~b,
  1,  1,
  1,  2,
  1,  3,
  1,  4,
  1,  5,)
k <- 10
df2 %>% 
  mutate(c = case_when(
    row_number() == 1 ~ k,
    row_number() != 1 ~ lag(c) + a - b))
#> Error in x[seq_len(xlen - n)]: object of type 'builtin' is not subsettable

Создано в 2020-03-05 пакетом Представить (v0.3.0)

Есть ли другой подход, который tidyverse, который обеспечивает вывод базового подхода?

1 Ответ

1 голос
/ 05 марта 2020

Мы можем сделать:

library(dplyr)
df2 %>%  mutate(c = k + cumsum(a-b))

# A tibble: 5 x 3
#      a     b     c
#  <dbl> <dbl> <dbl>
#1     1     1    10
#2     1     2     9
#3     1     3     7
#4     1     4     4
#5     1     5     0

, когда первое значение a - b не равно 0, мы можем использовать:

df2 %>%  mutate(c = c(k, k + cumsum(a-b)[-1]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...