Создайте фрейм данных, где соответствующие значения являются обратными интервалами t

#r

#r

Вопрос:

У меня есть огромный фрейм данных со следующим синтаксисом (четыре переменные — это просто пример, есть еще много переменных):

 Date.  Ticker. Revenue.   Price.

a1        b1     c1          d1
a2        b1     c2          d2
a3        b1     c3          d3
a4        b1     c4          d4
a5        b1     c5          d5
a1        b2     c6          d6
a2        b2     c7          d7
a3        b2     c8          d8
a4        b2     c9          d9
a5        b2     c10         d10
...
  

В примере тикеры b1 и b2 в порядке, но в реальном df они могут быть перепутаны.

Я хочу создать новый фрейм данных с ценами, которые возвращаются на t интервалов назад. Например, если мне нужно вернуться на 3 года назад, результат будет:

 Date.  Ticker. Revenue.   Price.

a1        b1     c1          
a2        b1     c2          
a3        b1     c3          
a4        b1     c4          d1
a5        b1     c5          d2
a1        b2     c6          
a2        b2     c7          
a3        b2     c8          
a4        b2     c9          d6
a5        b2     c10         d10
...
  

Ответ №1:

Мы можем использовать lag in dplyr для возврата t к интервалам.

 library(dplyr)
t <- 3
df %>% group_by(Ticker) %>% mutate(Price=  lag(Price, t))

#   Date  Ticker Revenue Price
#   <chr> <chr>  <chr>   <chr>
# 1 a1    b1     c1      NA   
# 2 a2    b1     c2      NA   
# 3 a3    b1     c3      NA   
# 4 a4    b1     c4      d1   
# 5 a5    b1     c5      d2   
# 6 a1    b2     c6      NA   
# 7 a2    b2     c7      NA   
# 8 a3    b2     c8      NA   
# 9 a4    b2     c9      d6   
#10 a5    b2     c10     d7   
  

Или shift в data.table :

 library(data.table)
setDT(df)[, Price := shift(Price, t), Ticker]
  

данные

 df <- structure(list(Date = c("a1", "a2", "a3", "a4", "a5", "a1", "a2", 
"a3", "a4", "a5"), Ticker = c("b1", "b1", "b1", "b1", "b1", "b2", 
"b2", "b2", "b2", "b2"), Revenue = c("c1", "c2", "c3", "c4", 
"c5", "c6", "c7", "c8", "c9", "c10"), Price = c("d1", "d2", "d3", 
"d4", "d5", "d6", "d7", "d8", "d9", "d10")), 
class = "data.frame", row.names = c(NA, -10L))
  

Ответ №2:

Мы можем использовать data.table методы

 library(data.table)
setDT(df)[, Price. := shift(Price., 3, fill = ""), Ticker.]
  

или с dplyr

 library(dplyr)
df %>%
    group_by(Ticker.) %>%
    mutate(Price = lag(Price., 3, default = ""))
  

-вывод

 # A tibble: 10 x 5
# Groups:   Ticker. [2]
#   Date. Ticker. Revenue. Price. Price
#   <chr> <chr>   <chr>    <chr>  <chr>
# 1 a1    b1      c1       d1     ""   
# 2 a2    b1      c2       d2     ""   
# 3 a3    b1      c3       d3     ""   
# 4 a4    b1      c4       d4     "d1" 
# 5 a5    b1      c5       d5     "d2" 
# 6 a1    b2      c6       d6     ""   
# 7 a2    b2      c7       d7     ""   
# 8 a3    b2      c8       d8     ""   
# 9 a4    b2      c9       d9     "d6" 
#10 a5    b2      c10      d10    "d7" 
  

Или base R с помощью ave

 df$Price <- with(df, ave(Price., Ticker., FUN = 
            function(x) c(rep('', 3), head(x, -3))))
  

данные

 df <- structure(list(Date. = c("a1", "a2", "a3", "a4", "a5", "a1", 
"a2", "a3", "a4", "a5"), Ticker. = c("b1", "b1", "b1", "b1", 
"b1", "b2", "b2", "b2", "b2", "b2"), Revenue. = c("c1", "c2", 
"c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"), Price. = c("d1", 
"d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10")), class = "data.frame", 
row.names = c(NA, 
-10L))