Лаг через несколько строк, используя вычисленный результат - PullRequest
0 голосов
/ 08 ноября 2019

Я пытаюсь создать новую переменную Rd, которая будет принимать значение lag(Rd), если переменная Vol равна 0. В противном случае она будет принимать значение OI/CumVol. Это вычисление выполняется с помощью Group, поэтому в случае первого наблюдения переменная Vol равна 0, я устанавливаю Rd=0. Вот пример того, что я хочу:

  Group   Vol      OI   CumVol   Rd   
  <date>   <dbl> <dbl> <dbl>    <dbl>
  2008-08-10  0     0      0       0      
  2008-08-10  100   100    100     1
  2008-08-10  0     100    300     1
  2008-08-10  0     100    400     1     
  2008-08-10  50    150    550    0.27
  2009-12-10  0     150     0      0 
  2009-12-10  50    30    50      0.6
  2009-12-10  0     20     50     0.6

Я пытался дважды мутировать с задержкой, но проблема в том случае, если Vol = 0 для повторяющихся строк, оно всегда принимает задержку дляпервый ряд и продолжается с 0 для остальных.

Data1<-Data1 %>%
group_by(Group) %>%
mutate(Rd1 = ifelse(Vol==0, 0, (Data1$OI/Data1$CumVol)))


Data1<-Data1 %>%
group_by(Group) %>%
mutate(Rd = ifelse(Vol==0, lag(Rd1), 
(Data1$OI/Data1$CumVol)))

Спасибо всем, кто найдет время ответить.

Ответы [ 2 ]

1 голос
/ 08 ноября 2019

Вы можете использовать accumulate. Если Vol (..2) равно 0, используйте предыдущий элемент (..1), в противном случае используйте Vol/CumVol (..3)

library(tidyverse)

df %>% 
  group_by(Group) %>%
  mutate(answer = 
           as.numeric(accumulate2(Vol, OI/CumVol, ~ if(..2 == 0) ..1 else ..3,
                      .init = 0)[-1]))


# # A tibble: 8 x 6
# # Groups:   Group [2]
#   Group        Vol    OI CumVol    Rd answer
#   <chr>      <int> <int>  <int> <dbl>  <dbl>
# 1 2008-08-10     0     0      0  0     0    
# 2 2008-08-10   100   100    100  1     1    
# 3 2008-08-10     0   100    300  1     1    
# 4 2008-08-10     0   100    400  1     1    
# 5 2008-08-10    50   150    550  0.27  0.273
# 6 2009-12-10     0   150      0  0     0    
# 7 2009-12-10    50    30     50  0.6   0.6  
# 8 2009-12-10     0    20     50  0.6   0.6  

Используемые данные

structure(list(Group = c("2008-08-10", "2008-08-10", "2008-08-10", 
"2008-08-10", "2008-08-10", "2009-12-10", "2009-12-10", "2009-12-10"
), Vol = c(0L, 100L, 0L, 0L, 50L, 0L, 50L, 0L), OI = c(0L, 100L, 
100L, 100L, 150L, 150L, 30L, 20L), CumVol = c(0L, 100L, 300L, 
400L, 550L, 0L, 50L, 50L), Rd = c(0, 1, 1, 1, 0.27, 0, 0.6, 0.6
)), row.names = c(NA, -8L), class = "data.frame")
1 голос
/ 08 ноября 2019
library(tidyverse)

dt = read.table(text = "
Group   Vol  OI   CumVol Rd   
  2008-08-10  0     0      0       0      
  2008-08-10  100   100    100     1
  2008-08-10  0     100    300     1
  2008-08-10  0     100    400     1     
  2008-08-10  50    150    550    0.27
  2009-12-10  0     150     0      0 
  2009-12-10  50    30    50      0.6
  2009-12-10  0     20     50     0.6
", header=T)

dt %>%
  group_by(Group) %>%
  mutate(Rd1 = ifelse(Vol==0, NA, OI/CumVol),          # calculate 
         Rd1 = ifelse(row_number() == 1, 0, Rd1)) %>%  # replace NAs with 0 in 1st rows only
  fill(Rd1) %>%                                        # get the previous non NA value
  ungroup()

# # A tibble: 8 x 6
#   Group        Vol    OI CumVol    Rd   Rd1
#   <fct>      <int> <int>  <int> <dbl> <dbl>
# 1 2008-08-10     0     0      0  0    0    
# 2 2008-08-10   100   100    100  1    1    
# 3 2008-08-10     0   100    300  1    1    
# 4 2008-08-10     0   100    400  1    1    
# 5 2008-08-10    50   150    550  0.27 0.273
# 6 2009-12-10     0   150      0  0    0    
# 7 2009-12-10    50    30     50  0.6  0.6  
# 8 2009-12-10     0    20     50  0.6  0.6 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...