多行引用条件(for循环)

Referencing conditions in multiple rows (for loop)

我在使用 for 循环引用多行中发生的条件时遇到问题。

思路如下。有一个包含 LastPrice 和 KCT 列的数据框。想要将 SignalBinary 列添加到数据框,并且 if

1) LastPrice[j] > KCT[j] 在任意 3 个连续行中,&

2) LastPrice[j+1] - LastPrice [j+1+3] > 12 在任何行 j+1 到 j+1+10 中(即以下 10 行)

然后想在SignalBinary[i]中记录一个1。

df <- data.frame(nrow =20, ncol =2)
df <- data.frame(LastPrice = c(1221,1220,1220,1217,1216,1218,1216,1216,1217,1220,1219,1218,1220,1216,1217,1218,1218,1207,1206,1205), KCT = c(1218,1218,1219,1218,1221,1217,1217,1216,1219,1216,1217,1216,1219,1217,1218,1217,1217,1217,1219,1217))
df$SignalBinary <-for(j in1:20){for(i in1:10){ifelse (df$LastPrice[j]> df$KCT[j]& df$LastPrice[j+1]> df$KCT[j+1]& df$LastPrice[j+2]> df$KCT[j+2]& df$LastPrice[j+i]- df$LastPrice[j+i+3]>12,1,0)}}

根据数据,本应预期代码在第 10 行和第 11 行记录 1,其余记录 0。但我做错了什么。 运行 该代码没有给出错误信息,但它没有创建 df$SignalBinary。 运行 df$SignalBinary 说 NULL。

顺便说一下,这样做的目的是将代码应用于大型价格数据库,运行 二进制信号的统计数据。

希望有人能提供帮助。非常感谢

有一件事是不正确的,即您没有从 ifelse 语句中返回任何内容(如果满足(未)满足条件,您当前有 1 和 0 作为操作)。我认为(但不要引用我的话)我已经以更简单的方式解决了你的问题,没有使用嵌套 for 循环。

df <- data.frame(nrow = 20, ncol = 2)
df <- data.frame(LastPrice = c( 1221, 1220, 1220, 1217, 1216,  1218 , 1216, 1216, 1217, 1220,     1219, 1218, 1220, 1216, 1217, 1218, 1218, 1207, 1206, 1205), KCT = c( 1218, 1218, 1219, 1218, 1221,  1217 , 1217, 1216, 1219, 1216, 1217, 1216, 1219, 1217, 1218, 1217, 1217, 1217, 1219, 1217))

df$SignalBinary <- as.numeric(df$LastPrice >= df$KCT & 
                      c(rep(FALSE ,3), diff(df$LastPrice, lag=3) >= 3)) 

所以我为向量设置了两个必须满足的条件。首先,df$LastPrice 必须大于(或等于)df$KCT。其次,df$LastPrice 之间的滞后差异必须大于或等于 3。我用 FALSE 填充前 3 个值,以使两个向量的长度相当。如果两个条件都满足,它会记录 TRUE,我将其转换为数字,然后将新列放在 data.frame 中。

只需将玩具示例中的值替换为您的应用程序所需的值,我认为这应该可行。

已解决!发布解决方案。比我想象的要复杂得多。必须将 StrongMove 的大小从 12 更改为 3,否则根据我在此示例中提供的数据将得不到任何信号。

#Data
df <- data.frame(LastPrice = c( 1221, 1220, 1220, 1217, 1216,  1218 , 1216, 1216, 1217, 1220, 1219, 1218, 1220, 1216, 1217, 1218, 1218, 1207, 1206, 1205), KCT = c( 1218, 1218, 1219, 1218, 1221,  1217 , 1217, 1216, 1219, 1216, 1217, 1216, 1219, 1217, 1218, 1217, 1217, 1217, 1219, 1217))

#Define inputs
StrongMoveWindow = 10     # up to this far below the current row
StrongMoveDur = 3         # check row against another this far down
StrongMoveSize = 3        # for a difference at least this big
PvsKCTDur = 3

#Set variables and define loop boundaries
base_rows = 1:(nrow(df) - StrongMoveDur)  # can't check more than this
candidate_max = pmin(base_rows + StrongMoveWindow, nrow(df) - StrongMoveDur) # for a given base row, this is the maximum row to start checking against
df$StrongMove = rep(NA, nrow(df))
df$SignalBinary = rep(NA, nrow(df)) # pre-allocate a vector of results

#Make StrongMove variable
for (i in seq_along(base_rows)) {
  df$StrongMove[i] = as.numeric(
    any(
      df$LastPrice[(i + 1):candidate_max[i]] - 
        df$LastPrice[((i + 1):candidate_max[i]) + StrongMoveDur] > StrongMoveSize))}

#Make ContPvsKCT variable
library(data.table)
setDT(df)
df[, SingPvsKCT := as.integer(LastPrice > KCT)]
df[, ContPvsKCT := do.call(pmin, shift(SingPvsKCT, 0:(PvsKCTDur-1), type="lead"))]

#Make SignalBinary variable
df$SignalBinary <- ifelse (df$ContPvsKCT == 1 & df$StrongMove == 1, 1, 0)

非常感谢@Gregor @HubertL @Chris @Psidom @brittenb @Frank