Как использовать для l oop для создания и заполнения столбцов? - PullRequest
3 голосов
/ 24 января 2020

У меня есть простой набор данных временного ряда с 10 переменными - я хочу создать для l oop (или функцию), которая создает переменную «изменение по сравнению с предыдущим месяцем» и «изменение процента по сравнению с переменной предыдущего месяца» для каждая переменная во временных рядах (кроме даты). Я знаю, что могу просто написать код для каждого конкретного столбца, но хотел бы оптимизировать его, поскольку столбцов много.

Вот как выглядят мои данные: «Дата», «Продажи», «Цена» Вот некоторые имена столбцов:

+----+---+---+---+---+---+---+---+--
| Date       |   Sales   |  Price  | 
+----+---+---+---+---+---+---+---+--
| 01Aug2019  | 4         | 15      |
| 01Sept2019 | 6         | 30      |
| 01Oct2019  | 10        | 44      |
+----+---+---+---+---+---+---+---+--

Вот как я хочу, чтобы это выглядело с использованием for l oop (или любой функции)

+----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| Date       |   Sales   |  chg_Sales  | pct_chg_Sales |   Price |  chg_Price  | pct_chg_Price| 
+----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 01Aug2019  | 4         | NA          |NA             |  15     | NA          |NA            |
| 01Sept2019 | 6         | 2           |50%            |  30     | 15          |100%          |
| 01Oct2019  | 10        | 4           |66%            |  44     | 14          |46%           |
+----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

Я попробовал код ниже, но он не работал

add_column <- function (x, y){
  setDT (x)[,pct_chg_y:= (y - shift (y,1, type="lag")/shift (,1, type="lag")*100]

}

Ответы [ 2 ]

2 голосов
/ 25 января 2020

Вот вариант с data.table, где мы указываем интересующие столбцы в .SDcols, создаем столбец 'chg_', вычитая .SD (Подмножество Data.table) из lag, т. Е. shift из .SD, затем на втором шаге создайте 'pct_chg, разделив shift на столбцы' chg_ ', используя Map

nm1 <- c("Sales", "Price")
setDT(df1)[,  paste0("chg_", nm1)  :=  .SD - shift(.SD), .SDcols = nm1]
df1[, paste0("pct_chg_", nm1) :=   
      Map(function(x, y)  100 * (y/shift(x)), .SD, mget(paste0("chg_", nm1))),
               .SDcols = nm1]
df1
#         Date Sales Price chg_Sales chg_Price pct_chg_Sales pct_chg_Price
#1:  01Aug2019     4    15        NA        NA            NA            NA
#2: 01Sept2019     6    30         2        15      50.00000     100.00000
#3:  01Oct2019    10    44         4        14      66.66667      46.66667

data

df1 <- structure(list(Date = c("01Aug2019", "01Sept2019", "01Oct2019"
), Sales = c(4, 6, 10), Price = c(15, 30, 44)), 
        class = "data.frame", row.names = c(NA, 
-3L))
1 голос
/ 25 января 2020
library(dplyr)
library(scales)

df1 %>% 
  arrange(Date) %>% 
  mutate_at(.vars = c("Sales", "Price"), list(chg = ~(. - lag(.)),
                                              pct_chg = ~percent((. - lag(.))/lag(.))))

  #         Date Sales Price Sales_chg Price_chg Sales_pct_chg Price_pct_chg
  # 1 2019-08-01     4    15        NA        NA           NA%           NA%
  # 2 2019-09-01     6    30         2        15         50.0%        100.0%
  # 3 2019-10-01    10    44         4        14         66.7%         46.7%
...