2017-10-10 1 views
2

에서 루프를 사용하지 않는 것이 Rcpp를 사용하는 방법을 다음과 같습니다 : 모든 열 또는 행 요소에 어떤 패턴이 없습니다내가 XTS 포맷 데이터 (데이터)가 R

       A 
2008-01-14 09:29:59   10 
2008-01-14 09:29:59   0.1 
2008-01-14 09:30:00   0.9 
2008-01-14 09:30:00   0.1 
2008-01-14 09:30:00   0.2 
2008-01-14 09:30:00   0.4 
2008-01-14 09:30:00   0.6 
2008-01-14 09:30:00   0.7 
2008-01-14 09:30:02   1.5 
2008-01-14 09:30:06   0.1 
2008-01-14 09:30:06   0.1 
2008-01-14 09:30:07   0.9 
2008-01-14 09:30:07   0.2 
2008-01-14 09:30:10   0.4 
2008-01-14 09:30:10   0.3 
2008-01-14 09:30:25   1.5 

.

데이터는 POSIXct 클래스 개체에 의해 인덱싱됩니다. '1 초', '3 초'라는 새로운 열을 만듭니다. 열 '1 초'에 대해 각 행에 대해 xts 시간 객체에 따라 다음 1 초 내에 다음 관찰을 찾고 행의 'A'값을 기록하려고합니다. 다음 초 내에 아무런 관찰이 없다면 NA에 해당 행의 $ 1 초를 넣으십시오.

마찬가지로 "3 초"열의 경우 각 행에 대해 xts 시간 객체에 따라 다음 3 초 내에 선행 관찰을 찾고 싶습니다. 다음 3 초 내에 동일한 시간 소인이있는 행이 여러 개있는 경우 마지막 관찰 만 사용하십시오.

다음 3 초 내에 아무런 관찰이 없다면 NA에 그 행에 3 초의 데이터를 입력하십시오. 예를 들어, 나는 다음과 같은 결과를 기대 :

       B 1second 3second 
2008-01-14 09:29:59   10 0.7  1.5   
2008-01-14 09:29:59   0.1 0.7  1.5 
2008-01-14 09:30:00   0.9 NA  1.5 
2008-01-14 09:30:00   0.1 NA  1.5 
2008-01-14 09:30:00   0.2 NA  1.5 
2008-01-14 09:30:00   0.4 NA  1.5 
2008-01-14 09:30:00   0.6 NA  1.5 
2008-01-14 09:30:00   0.7 NA  1.5 
2008-01-14 09:30:02   1.5 NA  NA 
2008-01-14 09:30:06   0.1 0.2  0.2 
2008-01-14 09:30:06   0.1 0.2  0.2 
2008-01-14 09:30:07   0.9 NA  0.3 
2008-01-14 09:30:07   0.2 NA  0.3 
2008-01-14 09:30:10   0.4 NA  0.3 
2008-01-14 09:30:10   0.3 NA  NA 
2008-01-14 09:30:25   1.5 NA  NA 

여기에 내 현재 코드, 그것은 작동하지만, 아주 천천히.

TimeStmp is the POSIXct object. 
     TimeHorizon<-c(1,3) 
     for(j in 1:nrow(data)){ 
     a<-sapply(TimeHorizon,function(x) which(TimeStmp==TimeStmp[j] +x)) 
     for(k in 1:length(a)){ 
      if (length(a[[k]]>0)){ 
      data[j,k+1]<-(data$B)[last(a[[k]])] 
      } 
     } 
     } 

for 루프를 사용하지 않으려면 Rcpp를 사용할 수 있는지 궁금합니다. 도움을 많이 주셔서 감사합니다.

+0

[경쟁 색인을 계산하는 방법을 피하는 방법] (https://stackoverflow.com/questions/42020341/how-to-avoid-a-loop-to-calculate-competition-index) – Mateusz1981

답변

1

코드에 너무 행복하지,하지만 하나 개의 방법이 될 수 있습니다

temp1 <- test[! duplicated(test$timestamp, fromLast = T), ] 
for (i in c(0,rep(1,3))) { 
    temp1$timestamp <- temp1$timestamp - i 
    test <- merge(test, temp1, by = "timestamp", all.x = T) 
} 
colnames(test) <- c("timestamp", "B", "0second", "1second", "2second", "3second") 
test$`3second` <- test[-1][cbind(1:nrow(test), max.col(!is.na(test[-1]), "last"))] 
test$`3second`[shift(test$timestamp,1,type = "lead") - test$timestamp > 3 | is.na(shift(test$timestamp,1,type = "lead") - test$timestamp)] <- NA 
test <- test[c("timestamp", "B", "1second", "3second")] 
test 
#    timestamp B 1second 3second 
# 1 2008-01-14 09:29:59 0.1  0.7  1.5 
# 2 2008-01-14 09:29:59 10.0  0.7  1.5 
# 3 2008-01-14 09:30:00 0.9  NA  1.5 
# 4 2008-01-14 09:30:00 0.1  NA  1.5 
# 5 2008-01-14 09:30:00 0.2  NA  1.5 
# 6 2008-01-14 09:30:00 0.4  NA  1.5 
# 7 2008-01-14 09:30:00 0.6  NA  1.5 
# 8 2008-01-14 09:30:00 0.7  NA  1.5 
# 9 2008-01-14 09:30:02 1.5  NA  NA 
# 10 2008-01-14 09:30:06 0.1  0.2  0.2 
# 11 2008-01-14 09:30:06 0.1  0.2  0.2 
# 12 2008-01-14 09:30:07 0.9  NA  0.3 
# 13 2008-01-14 09:30:07 0.2  NA  0.3 
# 14 2008-01-14 09:30:10 0.3  NA  0.3 
# 15 2008-01-14 09:30:10 0.4  NA  NA 
# 16 2008-01-14 09:30:25 1.5  NA  NA 

편집 : 그냥 당신이 Rcpp을 사용할 것을 보았다. 그럼이 대답을 무시하십시오. :)

EDIT2 : 내 코드 설명. 설명이 최상이 아닌 경우 실례합니다 : 열을 반복하는 대신, 먼저 각 시간 소인 (행 1)에 대한 마지막 관찰을 얻습니다. 그런 다음 원래 데이터 프레임에 "left_joins"합니다. 그 다음 타임 스탬프에서 1 초를 뺀 후 원래 데이터 프레임에 다시 "left_joins"합니다. 이것은 1 초, 2 초 및 3 초 지연을 설명하기 위해 3 번 반복됩니다 (2-5 줄). 이제는 같은 행에 "올바른"요소가 포함 된 데이터 프레임입니다. 그것은 올바른 열을 찾는 문제 일뿐입니다. 올바른 열은 해당 행 (행 7)에 대해 na이없는 가장 큰 열입니다. 우리는 여전히 na을 다음 3 초 (8 행)에서 후속 관찰이없는 행으로 설정해야합니다. 그렇게하면 불필요한 열 (9 행)을 제거 할 수 있습니다. 당신이 Rcpp 솔루션을 원하는 경우

+0

코드 단 하나의 대답은 그들이 질문에서 문제를 어떻게 해결했는지 설명하지 않기 때문에 낙담합니다. 이 질문에 대한 답과 문제 해결 방법을 설명하기 위해 대답을 업데이트하십시오. [좋은 답변 작성 방법] (https://stackoverflow.com/help/how-to-answer)을 검토하십시오. – FluffyKitten

1

당신이 그런

#include <Rcpp.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
NumericVector name_me(List df, double nsec) { 

    NumericVector TimeStmp = df["TimeStmp"]; 
    NumericVector B  = df["B"]; 
    int n = B.size(); 
    int i, j, k, ndup; 
    double time; 

    NumericVector res(n); 

    for (i = 0; i < n; i++) { 

    // get last for same second 
    for (ndup = 0; (i+1) < n; i++, ndup++) { 
     if (TimeStmp[i+1] != TimeStmp[i]) break; 
    } 

    // get last value within nsec 
    time = TimeStmp[i] + nsec; 
    for (j = i+1; j < n; j++) { 
     if (TimeStmp[j] > time) break; 
    } 

    // fill all previous ones with same value 
    res[i] = (j == (i+1)) ? NA_REAL : B[j-1]; 
    for (k = 1; k <= ndup; k++) res[i-k] = res[i]; 
    } 

    return res; 
} 

을 사용할 수 있습니다,이 .cpp 파일을 소싱 한 후, 당신은 단지에 inconstitency가 있음을

name_me(df, 1) 
name_me(df, 3) 

주를 호출 할 필요가 당신의 (n-2) 번째 행을 3 초 동안 표시합니다.