2017-10-10 6 views
2

J'ai données format XTS (données) ressemble à ceci:comment utiliser CRPP pour éviter d'utiliser des boucles en 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 

Il n'y a pas de modèle dans tout élément de colonne ou une ligne.

Les données sont indexées par un objet de classe POSIXct. Je crée de nouvelles colonnes appelées '1 seconde', '3 secondes'. Pour la colonne '1 seconde', pour chaque ligne, je veux trouver l'observation suivante dans la prochaine seconde en fonction de leur objet temps xts et enregistrer la valeur 'A' de la ligne. Si aucune observation dans les prochaines secondes, mettre NA dans les données $ 1seconde dans cette rangée.

De même, pour la colonne "3 secondes", pour chaque ligne, je souhaite trouver l'observation principale dans les 3 secondes suivantes en fonction de leur objet temps xts. S'il y a plusieurs lignes avec le même horodatage dans les 3 prochaines secondes, alors utilisez la dernière observation seulement.

Si aucune observation dans les 3 prochaines secondes, mettez NA dans les données $ 3second dans cette rangée. Par exemple, je compte les résultats suivants:

       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 

Voici mon code actuel, cela fonctionne, mais très lent. Je me demande s'il est possible d'utiliser le Rcpp pour éviter d'utiliser la boucle for. Merci beaucoup pour l'aide.

+0

Copie possible de [Comment éviter une boucle pour calculer l'indice de concurrence] (https://stackoverflow.com/questions/42020341/how-to-avoid-a-loop-to-calculate-competition-index) – Mateusz1981

Répondre

1

Pas trop heureux avec le code, mais il pourrait être une approche:

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 

EDIT: Je viens de voir que vous voulez utiliser CRPP. Eh bien, ignorez simplement cette réponse. :)

EDIT2: Explication à mon code. Excusez-moi si l'explication n'est pas la meilleure: Au lieu de boucler sur la colonne, on obtient d'abord la dernière observation pour chaque horodatage (ligne 1). Puis un "left_joins" ceci sur l'image originale. Ensuite, on soustrait une seconde de l'horodatage et "left_joins" sur l'image originale. Ceci est répété 3 fois pour tenir compte des retards de 1 seconde, 2 secondes et 3 secondes (lignes 2-5). Maintenant, c'est un dataframe qui contient l'élément "correct" dans la même ligne; c'est juste une question de trouver la bonne colonne. La colonne correcte est la plus grande qui n'a pas na pour cette ligne (ligne 7). Nous devons encore définir na les lignes qui n'ont pas d'observation de suivi dans les trois prochaines secondes (ligne 8). Après cela, nous pouvons supprimer les colonnes inutiles (ligne 9) et c'est fait.

+0

Code -les réponses seulement sont découragées parce qu'elles n'expliquent pas comment elles résolvent le problème dans la question. Pensez à mettre à jour votre réponse pour expliquer ce que cela fait et comment elle résout le problème. Veuillez consulter [Comment écrire une bonne réponse] (https://stackoverflow.com/help/how-to-answer) – FluffyKitten

1

Si vous voulez une solution CRPP vous pouvez utiliser

#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; 
} 

Puis, après l'approvisionnement de ce fichier .cpp, il vous suffit d'appeler

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

Notez qu'il ya un inconstitency dans votre (n-2) ème rangée pendant 3 secondes.