我在使用for循环引用多行中发生的条件时遇到了问题。
这个想法如下。有一个包含LastPrice和KCT列的数据框。想要将SignalBinary列添加到数据帧,如果
1)LastPrice [j]> KCT [j]连续3行,&
2)LastPrice [j + 1] - LastPrice [j + 1 + 3]>在行j + 1到j + 1 + 10(即10行以下)的任何行中的图12中的
然后想在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。
BTW的目的是将代码应用于大型价格数据库,以运行二进制信号的统计数据。希望有人可以提供帮助。非常感谢你
答案 0 :(得分:0)
有一件事是不正确的,那就是你没有从你的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
中。
只需将您玩具示例中的值替换为应用程序所需的值,我认为这应该有效。
答案 1 :(得分:0)
解决!发布解决方案。比我想象的要复杂得多。不得不将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