2017-10-31 5 views
0

날짜 범위에 대한 주가의 시가 총액과 가격이 포함 된 데이터 집합이 있습니다. 기간 중 일부 날짜가 누락되었습니다. 나는 x 일 전의 가격 (x는 일일 차이를 나타내는 숫자의 목록)에서 현재 가격이 얼마만큼 변경되었는지를 보여주는 새로운 변수를 효율적으로 만들고 싶습니다.불완전한 날짜 열을 사용하여 R의 동적 날짜 차이에 따라 변경 변수를 효율적으로 만드는 방법

예를 들어, 내가 가진 D1 :

d1 <- structure(list(Date = c(as.Date("2017-10-28"), as.Date("2017-10-27"), as.Date("2017-10-26"), 
          as.Date("2017-10-24"), as.Date("2017-10-21"), as.Date("2017-10-20")), 
       Price = c(100L, 98L, 102L, 97L, 96L, 100L), 
       MC = c(50L, 55L, 49L, 47L, 50L, 46L)), 
      .Names = c("Date", "Price", "MC")) 

d1<-as.data.frame(d1) 

내 욕망 (D2)를 만드는 것입니다 (I 1과 2 일간의 변화에 ​​관심이 가정) : 변경 변수는

d2 <- structure(list(Date = c(as.Date("2017-10-28"), as.Date("2017-10-27"), as.Date("2017-10-26"), 
          as.Date("2017-10-24"), as.Date("2017-10-21"), as.Date("2017-10-20")), 
       Price = c(100L, 98L, 102L, 97L, 96L, 100L), 
       MC = c(50L, 55L, 49L, 47L, 50L, 46L), 
       Delta1Price = c(0.0204, -0.0392, NA, NA, -0.04, NA), 
       Delta1MC = c(-0.0909, 0.12244, NA, NA, 0.0869, NA), 
       Delta2Price = c(-0.0196, NA, 0.0515, NA, NA, NA), 
       Delta2MC = c(0.0204, NA, 0.04255, NA, NA, NA)), 
      .Names = c("Date", "Price", "MC", "Delta1Price", "Delta1MC", "Delta2Price", "Delta2MC")) 

d2<-as.data.frame(d2) 

(currentValue - previousValue)/PreviousValue에 의해 계산 됨

for 루프를 사용하여 이렇게하는 것이 비효율적 인 방법입니다.

# Assume d1 and d2 are dataframes # 
nms <- colnames(d1)[c(2:3)] 
changeList <- c(1:2) 
for (i in changeList){ 

    #record the dates that will be used to calculate changes 
    currentDate <- d1$Date 
    revDate <- currentDate-i 

    #filter out the rows for the older relevant date 
    revData <- d1 %>% 
     dplyr::filter(d1$Date %in% revDate) 

    #Get the newer dates that are available 
    newCurDate <- revData$Date+i 
    newCurData <- d1 %>% 
    dplyr::filter(d1$Date %in% newCurDate) 

    #calculate the change variables 
    changes <- (newCurData[, nms] - revData[,nms])/revData[,nms] 

    #dynamically name these new change variables 
    newCurData[, paste("Delta", paste(i, nms, sep=""), sep="")]<- changes 

    #merge the data to get desired outcome 
    d1 <- merge(d1, newCurData, all=TRUE) 
} 
#final output should be the same d2 that I structured 
d2 <- d1 

답변

0

첫째, 당신은 그들이 나쁜 것을 R.하지에서 루프를 방지해야 자체하지만 대부분의 기능이 벡터를 받아들이고 당신은 아마 순진 루프에 도달하지 않을 방법으로 그것을 위해 최적화되어 있습니다. 그리고 일반적으로 루프 없이는 읽기가 쉽습니다.

두 번째로, 벡터로 작업하는 경우 강력한 패키지에는 "지연"방법이 있습니다. (values - lag(values))/lag(values)이 대부분의 작업을 수행 할 수 있도록 dplyrlag(...)이라고합니다. data.tableshift(..., n=1)이라고합니다.

셋째, data.tablerolling joins을 활용할 수 있습니다. 일반적으로 날짜 일치로 설명됩니다. 이 기능은 dplyr에 아직 구현되지 않았습니다. here을 참조하십시오. 자동 조인을하고 있음을 올바르게 알고 있습니까? 그런 다음 데이터 세트를 d1 %>% left_join(d1)dplyr 또는 d1[d1]data.table에 명시 적으로 결합해야합니다.

마지막으로, 작업 전용 패키지를 사용하지 않는 이유는 무엇입니까? 금융 자산에 대한 수익률 계산은 너무나도 친숙한 것으로 보입니다. 나는 당신 만이이 문제에 직면하고 있다고 의심합니다. 작업 페이지에서 financetime-series에 대한 기회가 더 많을 수 있습니다.


마무리합니다. 여기에 설명을

d1[ 
    d1, 
    list(
    Date, Previous_date=Date2, Gap=Date-Date2, 
    Price, Previous_price=i.Price, 
    Return=(Price-i.Price)/i.Price 
    ), 
    on="Date<Date2", 
    mult='first' 
] 

:

library(datat.table) 
d1 <- data.table(
    Date = as.Date(c("2017-10-28", "2017-10-27", "2017-10-26", "2017-10-24", "2017-10-21", "2017-10-20")), 
    Price = c(100L, 98L, 102L, 97L, 96L, 100L) 
) 
d1[,Date2:=Date] # duplicates the time column, see after 

이 내가 이해 문제를 해결 d1[d1]data.table 패키지에 고전 병합입니다. 병합에 사용할 열을 지정하는 방법은 여러 가지가 있지만 여기서는 on을 사용합니다.이 열은 on-th-fly 병합 열을 지정합니다. v1.9.8에서 병합에 대한 부등식을 사용할 수 있습니다! 여기에 우리가 간다 : on="Date<Date2". 왼쪽은 첫 번째 d1 (괄호 앞)을 나타내고 오른쪽은 두 번째 (괄호 안쪽)를 나타냅니다.

그러나 이렇게하면 개의 로트가 (모든 이전 관측치가 일치 함)이되고 가장 최근의 것이므로 mult='first'입니다.이 작업을하려면 시간에 따라 데이터 집합을 정렬해야합니다.

마지막으로 중요한 것은 계산을 할 수 있다는 것입니다. 우리가 출력물에 넣고 자하는 모든 것은 명령어 list() 안에 넣어 져야합니다. i. 접두사를 사용하여 과 같이 대괄호 안에있는 d1을 접두사로 사용할 수 있습니다. 아쉽게도 병합에 사용되는 변수 (Date은 여기)가 작동하지 않으므로 i.DateDate과 같은 결과를 낳습니다. 이것은 아마도 버그 일 뿐이지 만 한편 손에 Date 열을 Date2이라는 이름으로 복사 했으므로 여기에 Gap=Date-Date2을 사용할 수 있습니다.


나는 반드시 난해한 문법 data.table을 좋아하지 않아. 하지만 여기에 dplyr 뒤처져 있습니다. 곧 적용될 것이지만, it seems.

+0

도움말 Arthur에게 감사드립니다. 나는 재정과 시계열에 관한 과제 페이지를 점검 할 것이다. 나는 자기 문제를 설명하기 위해서만 자기 조인을했으나 그것이 가장 효율적인 방법인지는 확신 할 수 없었다. 지연 방법의 관점에서 이전에 몇 가지 게시물을 살펴 봤지만 시계열이 일정한 간격을 유지하면 제대로 작동하는 것으로 보입니다. 필자의 경우에는 몇 가지 누락 날짜가 있기 때문에 일관성없는 시계열 데이터가 있습니다. –

+0

내 답변을 수정했습니다. 나는 그렇게 간단하지 않다는 것을 인정한다 : D – Arthur