Вычисление нового столбца во фрейме данных на основе существующих столбцов - PullRequest
2 голосов
/ 06 августа 2020

У меня есть этот фрейм данных с 5 столбцами, где stock - это current_stock. И мне нужен новый столбец stock_over_time, который затем вычисляется как stock_over_time = stock - продажа + покупка.

df=tibble(article=rep("article one",5), 
week=c(1,2,3,4,5), 
sales=10, 
purchase=c(5,0,5,5,0), 
stock=c(50))

# A tibble: 5 x 5
  article      week sales purchase stock
  <chr>       <dbl> <dbl>    <dbl> <dbl>
1 article one     1    10        5    50
2 article one     2    10        0    50
3 article one     3    10        5    50
4 article one     4    10        5    50
5 article one     5    10        0    50

Мой последний фрейм данных должен выглядеть так:

# A tibble: 5 x 5
  article      week sales purchase stock stock_over_time
  <chr>       <dbl> <dbl>    <dbl> <dbl>  <dbl>
1 article one     1    10        5    50     NA
2 article one     2    10        0    50     45
3 article one     3    10        5    50     35
4 article one     4    10        5    50     30
5 article one     5    10        0    50     25

... где stock_over_time рассчитывается как:

50 - 10 + 5 = 45
45 - 10 + 0 = 35
35 - 10 + 5 = 30
30 - 10 + 5 = 25

Как мне это сделать?

Ответы [ 2 ]

3 голосов
/ 06 августа 2020

Вы можете использовать cumsum():

library(dplyr)

df %>% 
  mutate(stock_over_time = lag(stock + cumsum(purchase - sales)))

# A tibble: 5 x 6
  article      week sales purchase stock stock_over_time
  <chr>       <dbl> <dbl>    <dbl> <dbl>           <dbl>
1 article one     1    10        5    50              NA
2 article one     2    10        0    50              45
3 article one     3    10        5    50              35
4 article one     4    10        5    50              30
5 article one     5    10        0    50              25
2 голосов
/ 06 августа 2020

Мы можем использовать рекурсивный способ сделать это, и он также должен работать со сложными случаями

df$stock_over_time <- df$stock
for(i in 2:nrow(df)) {
    df$stock_over_time[i] <- df$stock_over_time[i-1] - 
           df$sales[i-1] + df$purchase[i-1]
 }
 
df
# A tibble: 5 x 6
#  article      week sales purchase stock stock_over_time
#  <chr>       <dbl> <dbl>    <dbl> <dbl>           <dbl>
#1 article one     1    10        5    50              50
#2 article one     2    10        0    50              45
#3 article one     3    10        5    50              35
#4 article one     4    10        5    50              30
#5 article one     5    10        0    50              25

Или другой вариант: accumulate из purrr

library(purrr)
library(dplyr)
df %>% 
    mutate(stock_over_time = accumulate((purchase- sales)[-1], 
            ~ .x + .y, .init = first(stock)))
# A tibble: 5 x 6
#  article      week sales purchase stock stock_over_time
#  <chr>       <dbl> <dbl>    <dbl> <dbl>           <dbl>
#1 article one     1    10        5    50              50
#2 article one     2    10        0    50              40
#3 article one     3    10        5    50              35
#4 article one     4    10        5    50              30
#5 article one     5    10        0    50              20

Или это можно записать как

df %>% 
    mutate(stock_over_time = accumulate(c(first(stock), 
         (purchase- sales)[-1]), ~ .x + .y))
...