2016-04-20 2 views
0

J'essaie de récupérer un numéro de ligne associé à la valeur max/min dans une fenêtre glissante. Je sous-divise ce numéro de ligne pour récupérer une valeur d'une colonne différente.R - Renvoie le numéro de ligne de la valeur max ou min dans la fenêtre glissante

votre demande, voici le dput (tête (DATAFRAME3)):

structure(list(Time = c("00:00:01|", "00:00:03|", "00:00:04|", 
"00:00:05|", "00:00:06|", "00:00:07|"), Average = c(8, 5.75, 
5.33333333333333, 5.23076923076923, 5.15, 5.15), NegativeChange = c(-3, 
-0.75, -0.333333333333333, -0.230769230769231, -0.15, -0.15), 
    PositiveChange = c(0, 0, 0.107843137254902, 0.210407239819005, 
    0.291176470588235, 0.291176470588235)), .Names = c("Time", 
"Average", "NegativeChange", "PositiveChange"), class = c("data.table", 
"data.frame"), row.names = c(NA, -6L), .internal.selfref = <pointer: 0x0000000001300788>) 

Voici un téléchargement d'un fichier de données de texte tronqué, et par la suite, le code je l'importer dans R et obtenir au point où je tentais de coder la partie Timestamp Fin:

http://textuploader.com/5ymml

code:

#prepare workspace...delete prior data and values 
rm(list=ls()) 

#Load packages 
library(data.table) 
library(dplyr) 

#set working directory, setwd(filepath) 
setwd() 

#load fixed width data, n = 39 
DATAFRAME <- read.fwf("Dataframe3_Truncated.txt", widths = c(9,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), header = FALSE, sep = "\t", skip = 4, na.strings = c("-")) 

#transform to data.table 
DATAFRAME <- data.table(DATAFRAME) 

#Calculate row averages, adding an "Average" column to the data set 
DATAFRAME2 <- DATAFRAME[, .(Average = rowMeans(.SD, na.rm = TRUE)), "V1"] 

#Calculate NegativeChange and PositiveChange using subscript method 
NegativeChange <- numeric(nrow(DATAFRAME2)) 
PositiveChange <- numeric(nrow(DATAFRAME2)) 
for (i in 1:(nrow(DATAFRAME2)-90)) { 
    y <- i 
    x <- i+90 
    NegativeChange[i] <- min(DATAFRAME2$Average[y:x]) - DATAFRAME2$Average[i] 
    PositiveChange[i] <- max(DATAFRAME2$Average[y:x]) - DATAFRAME2$Average[i] 
} 

#add NegativeChange and PositiveChange columns to datatable 
DATAFRAME3 <- DATAFRAME2[, .(Time = as.character(V1), Average, NegativeChange, PositiveChange)] 
DATAFRAME3 

PositiveChange est l'écart positif maximal de la moyenne [i] dans [i: i + 90]. NegativeChange est l'écart négatif maximal de la moyenne [i] dans [i: i + 90]. Le EndTimestamp, et pourquoi je suis en train de trouver le numéro de ligne de la valeur max/min, doit être pour maxl'horodatage auquel la moyenne est la plus élevée [i: i + 90] et minl'horodatage auquel la moyenne est la plus basse [i: i + 90]. J'ai essayé de déclencher la fonctionnalité EndTimestamp uniquement lorsque PositiveChange> = 1 ou NegativeChange < = -1.

exemples de code que j'ai essayé de trouver le numéro de ligne de valeur max sont ci-dessous:

#which.max 
EndTimestamp <- numeric(nrow(DATAFRAME3)) 
for (i in seq(nrow(DATAFRAME3))) { 
    X <- (i + 1) 
    y <- (i + 91) 
    z <- (i) 
    if (DATAFRAME3$PositiveChange[i] >= 1) { 
    EndTimestamp[i] <- DATAFRAME3[(which.max(DATAFRAME3$Average[x:y]) + z), Time] 
    } else { 
    EndTimestamp[i] <- NA 
    } 
} 



#which 
TimestampRowIndex <- c() 
TimestampRowActual <- c() 
EndTimestamp3 <- numeric(nrow(DATAFRAME3)) 
for (i in seq(nrow(DATAFRAME3))) { 
    X <- (i + 1) 
    y <- (i + 91) 
    z <- (i) 
    if (DATAFRAME3$PositiveChange[i] >= 1) { 
    TimestampRowIndex <- append(TimestampRowIndex, which(DATAFRAME3$Average[x:y] == max(DATAFRAME3$Average[x:y]))) 
    TimestampRowActual <- TimestampRowIndex[length(TimestampRowIndex)] + z 
    EndTimestamp3[i] <- DATAFRAME3[as.integer(TimestampRowActual), Time] 
    } else { 
    EndTimestamp3[i] <- NA 
    } 
} 

Aucune solution fonctionne pour trouver le maximum pour PositiveChange> = 1, et semblent faire pire lors de la transformation de trouvez le min pour NegativeChange < = -1. En raison de la nature des données, les lignes séquentielles dans lesquelles la moyenne> = 1 devrait dans la plupart des cas avoir le même horodatage de fin. Mais le code ci-dessus produit des horodatages ascendants. Et à un moment donné (lignes 928 à 973) produit des horodatages décroissants, ce qui n'a aucun sens.

Je suis sûr qu'il y a une réponse simple, mais étant nouveau pour R et le codage en général, j'ai passé des heures à essayer de le trouver en vain.

De même, la variable z est de corriger le fait que les fonctions which et which.max renvoient une valeur d'index basée sur la plage examinée (je pense). Donc, si la valeur maximale dans 500: 600 est dans la ligne 504 de la datatable, les fonctions qui vont retourner une valeur de 4. Y a-t-il un moyen de contourner cela, de sorte qu'il retournerait 504?

Suggestions? Heureux de fournir plus d'informations si nécessaire.

+0

Jetez un oeil à 'cummax' et' cummin'? – Gopala

+0

De même, il est préférable d'envoyer un échantillon de données d'entrée avec la sortie souhaitée. On peut fournir le code de travail en réponse. – Gopala

+0

Les questions qui cherchent une aide au débogage ("pourquoi ce code ne fonctionne-t-il pas?") Doivent inclure le comportement souhaité, un problème ou une erreur spécifique et le code le plus court nécessaire pour le reproduire dans la question elle-même. Les questions sans énoncé de problème clair ne sont pas utiles aux autres lecteurs. Voir: [mcve]. –

Répondre

0

Je ne comprends pas le but de votre code, pourquoi avez-vous besoin de déplacer des agrégats de fenêtre? Peut-être qu'il existe une structure de données plus adaptée à votre problème. Cependant, en utilisant des données données, je suggère ce qui suit:

"NegativeChange" est l'écart minimum de la moyenne dans un intervalle donné. C'est par définition la valeur minimale par intervalle. Vous recherchez des valeurs minmal (maximales) dans une fenêtre en mouvement. package RcppRoll provieds fonctions utiles pour cette tâche:

library(RcppRoll) 
DATAFRAME2$min_Average = roll_minl(Average, 90) 
DATAFRAME2$max_Average = roll_maxl(Average, 90) 

Dans votre prochaine étape que vous essayez d'obtenir le numéro de ligne (ou la position dans l'intervalle?) de valeur min/max par intervalle Si vous avez besoin de cette information, vous devrez probablement utiliser une boucle.

#Calculate row averages, adding an "Average" column to the data set 
DATAFRAME2 <- DATAFRAME[, .(Average = rowMeans(.SD, na.rm = TRUE)), "V1"] 

# calculate min/max of rolling Window 
for (i in 1:nrow(DATAFRAME2)) { 
    j = min(i+90, nrow(DATAFRAME2)) # upper bound of window 
    DATAFRAME2$min_Average[i] = min(DATAFRAME2$Average[i:j]) 
    DATAFRAME2$pos_min_Average[i] = (i-1) + which.min(DATAFRAME2$Average[i:j]) 
    DATAFRAME2$max_Average[i] = max(DATAFRAME2$Average[i:j]) 
    DATAFRAME2$pos_max_Average[i] = (i-1) + which.max(DATAFRAME2$Average[i:j]) 
} 
+0

Cela a fonctionné! Merci beaucoup. J'ai également appris quelques choses en examinant votre solution. Très appréciée. – biebz