R - return 滑动中最大值或最小值的数据表行数 window
R - return datatable row number of max or min value in sliding window
我试图在滑动 window 中检索与 max/min 值关联的行号。然后我对该行号进行子集化以从不同的列中检索值。
根据您的要求,这里是 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 并将其带到我试图对结束时间戳部分进行编码的代码:
代码:
#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 函数 return 一个基于被检查范围的索引值这一事实(我认为)。因此,如果 500:600 中的最大值在数据表的第 504 行中,则哪些函数将 return 值为 4。有没有办法解决这个问题,这样它就会 return 504?
建议?如果需要,很乐意提供更多信息。
我不明白你的代码的用途,为什么你需要移动 window 聚合?也许有一种数据结构更适合您的问题。但是,使用给定的数据,我建议如下:
"NegativeChange" 是给定区间内与平均值的最小偏差。根据定义,这是每个间隔的最小值。
您正在寻找移动 window 中的最小(最大)值。 RcppRoll 包为此任务提供了有用的函数:
library(RcppRoll)
DATAFRAME2$min_Average = roll_minl(Average, 90)
DATAFRAME2$max_Average = roll_maxl(Average, 90)
在下一步中,您将尝试获取每个间隔的 min/max 值的行号(或间隔中的位置?)
如果您需要此信息,您可能必须使用循环。
#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])
}
我试图在滑动 window 中检索与 max/min 值关联的行号。然后我对该行号进行子集化以从不同的列中检索值。
根据您的要求,这里是 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 并将其带到我试图对结束时间戳部分进行编码的代码:
代码:
#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 函数 return 一个基于被检查范围的索引值这一事实(我认为)。因此,如果 500:600 中的最大值在数据表的第 504 行中,则哪些函数将 return 值为 4。有没有办法解决这个问题,这样它就会 return 504?
建议?如果需要,很乐意提供更多信息。
我不明白你的代码的用途,为什么你需要移动 window 聚合?也许有一种数据结构更适合您的问题。但是,使用给定的数据,我建议如下:
"NegativeChange" 是给定区间内与平均值的最小偏差。根据定义,这是每个间隔的最小值。 您正在寻找移动 window 中的最小(最大)值。 RcppRoll 包为此任务提供了有用的函数:
library(RcppRoll)
DATAFRAME2$min_Average = roll_minl(Average, 90)
DATAFRAME2$max_Average = roll_maxl(Average, 90)
在下一步中,您将尝试获取每个间隔的 min/max 值的行号(或间隔中的位置?) 如果您需要此信息,您可能必须使用循环。
#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])
}