簡體   English   中英

R-在滑動窗口中返回數據表的最大值或最小值的行數

[英]R - return datatable row number of max or min value in sliding window

我正在嘗試檢索與滑動窗口中的最大值/最小值相關的行號。 然后,我要對該行號進行子集設置,以從其他列中檢索值。

根據您的請求,這里是dput(head(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>)

這是一個截斷的文本數據文件的上載,隨后是我用來將其導入R並將其傳遞到試圖對End Timestamp部分進行編碼的點的代碼:

http://textuploader.com/5ymml

碼:

#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是[i:i + 90]中與Average [i]的最大正偏差。 NegativeChange是[i:i + 90]中與Average [i]的最大負偏差。 EndTimestamp,以及為什么要嘗試查找Max / Min值的行號,對於max應該是平均值最高的時間戳[i:i + 90] ,對於min 是平均值是最高 的時間戳最低[i:i + 90] 我試圖讓EndTimestamp功能僅在PositiveChange> = 1或NegativeChange <= -1時才觸發。

我嘗試查找最大值行號的代碼示例如下:

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

這兩種解決方案都無法找到PositiveChange> = 1的最大值,並且在轉換為NegativeChange <= -1的最小值時似乎做得更糟。 由於數據的性質,在大多數情況下,平均值> = 1的連續行在大多數情況下應具有相同的結束時間戳記。 但是上面的代碼會產生遞增的時間戳。 並且在某一點(行928至973)產生下降的時間戳,這沒有任何意義。

我敢肯定有一個簡單的答案,但是對於R和一般的編碼來說,我已經花了數小時試圖找到它,但無濟於事。

同樣,z變量用於糾正which和which.max函數基於所檢查的范圍返回索引值的事實(我認為)。 因此,如果500:600中的最大值位於數據表的504行中,則哪個函數將返回值4。是否有辦法解決該問題,使其返回504?

有什么建議嗎? 如果需要,很高興提供更多信息。

我不了解您的代碼的目的,為什么需要移動窗口聚合? 也許有一個更適合您問題的數據結構。 但是,使用給定的數據,我建議以下幾點:

“ NegativeChange”是給定時間間隔內與平均值的最小偏差。 根據定義,這是每個間隔的最小值。 您正在移動的窗口中尋找最小值(最大值)。 RcppRoll軟件包為該任務提供了有用的功能:

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

在下一步中,您嘗試獲取每個間隔的最小值/最大值的行號(或間隔中的位置?)。如果您需要此信息,則可能必須使用循環。

#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])
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM