2016-04-24 25 views
1

我有9x3 dataframe DATA,其中一列有時間戳(DateTime),一個價格(Close)和一個二進制值(FOMCBinary)。記錄非連續的二進制事件(簡單的if子句問題)

我想添加列SignalBinary記錄1 IF關閉< X值(在此示例中爲1126)AND FOMCBinary> 0在下面兩行中的任何一行中,但只有在下面行中的SignalBinary = 0時(即do不想連續1s)。

在這裏的例子中,我只需要在14:15:00在SignalBinary下記錄1。我的編碼嘗試是在14:15:00和14:30:00記錄1。應該相當簡單,不明白爲什麼我的代碼不會產生所需的結果。我怎樣才能解決這個問題?

DATA <- structure(list(DateTime = structure(list(sec = c(0, 0, 0, 0,0, 0, 0, 0, 0), min = c(30L, 15L, 0L, 45L, 30L, 15L, 0L, 45L,30L), hour = c(15L, 15L, 15L, 14L, 14L, 14L, 14L, 13L, 13L),mday = c(27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L), mon = c(0L,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), year = c(116L, 116L, 116L,116L, 116L, 116L, 116L, 116L, 116L), wday = c(3L, 3L, 3L,3L, 3L, 3L, 3L, 3L, 3L), yday = c(26L, 26L, 26L, 26L, 26L,26L, 26L, 26L, 26L), isdst = c(0L, 0L, 0L, 0L, 0L, 0L, 0L,0L, 0L), zone = c("EST", "EST", "EST", "EST", "EST", "EST","EST", "EST", "EST"), gmtoff = c(NA_integer_, NA_integer_,NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_,NA_integer_, NA_integer_)), .Names = c("sec", "min", "hour","mday", "mon", "year", "wday", "yday", "isdst", "zone", "gmtoff"), class = c("POSIXlt", "POSIXt")), Close = c(1127.2, 1127.5,1126.9, 1128.3, 1125.4, 1122.7, 1122.8, 1117.3, 1116), FOMCBinary = c(0,0, 0, 0, 0, 0, 1, 0, 0)), .Names = c("DateTime", "Close", "FOMCBinary"), row.names = 2131:2139, class = "data.frame") 

Xvalue = 1126 

#For comparing lagged or forward rows 
rowShift <- function(x, shiftLen = 1L) { 
    r <- (1L + shiftLen):(length(x) + shiftLen) 
    r[r<1] <- NA 
    return(x[r]) } 

DATA$SignalBinary <- ifelse(
       DATA$Close < Xvalue & (
       rowShift(DATA$FOMCBinary, +1) > 0 | 
       (rowShift(DATA$FOMCBinary, +2) > 0 & rowShift(DATA$FOMCBinary, +1) == 0)) 
       , 1, 0) 

##Note rowShift(DATA$FOMCBinary, +1) is equivalent to DATA$FOMCBinary[seq(nrow(DATA))+1]## 

輸出的數據進行計算後:

   DateTime Close FOMCBinary SignalBinary 
2131 2016-01-27 15:30:00 1127.2   0   0 
2132 2016-01-27 15:15:00 1127.5   0   0 
2133 2016-01-27 15:00:00 1126.9   0   0 
2134 2016-01-27 14:45:00 1128.3   0   0 
2135 2016-01-27 14:30:00 1125.4   0   1 => UNWANTED 1 
2136 2016-01-27 14:15:00 1122.7   0   1 
2137 2016-01-27 14:00:00 1122.8   1   0 
2138 2016-01-27 13:45:00 1117.3   0   NA 
2139 2016-01-27 13:30:00 1116.0   0   NA 

非常感謝你。

+0

謝謝。 rowShift函數完美地工作。問題不在那裏。注意'DATA $ FOMCBinary [seq(nrow(DATA))+ 1]'產生相同的結果。不知道你的意思是說我不需要ifelse聲明。 – Krug

回答

1

仔細看了一下。你想在SignalBinary中刪除第一個連續的1,但你沒有通過SignalBinary掃描。這是一個粗略的代碼

DATA <- structure(list(DateTime = structure(list(sec = c(0, 0, 0, 0,0, 0, 0, 0, 0), min = c(30L, 15L, 0L, 45L, 30L, 15L, 0L, 45L,30L), hour = c(15L, 15L, 15L, 14L, 14L, 14L, 14L, 13L, 13L),mday = c(27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L), mon = c(0L,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), year = c(116L, 116L, 116L,116L, 116L, 116L, 116L, 116L, 116L), wday = c(3L, 3L, 3L,3L, 3L, 3L, 3L, 3L, 3L), yday = c(26L, 26L, 26L, 26L, 26L,26L, 26L, 26L, 26L), isdst = c(0L, 0L, 0L, 0L, 0L, 0L, 0L,0L, 0L), zone = c("EST", "EST", "EST", "EST", "EST", "EST","EST", "EST", "EST"), gmtoff = c(NA_integer_, NA_integer_,NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_,NA_integer_, NA_integer_)), .Names = c("sec", "min", "hour","mday", "mon", "year", "wday", "yday", "isdst", "zone", "gmtoff"), class = c("POSIXlt", "POSIXt")), Close = c(1127.2, 1127.5,1126.9, 1128.3, 1125.4, 1122.7, 1122.8, 1117.3, 1116), FOMCBinary = c(0,0, 0, 0, 0, 0, 1, 0, 0)), .Names = c("DateTime", "Close", "FOMCBinary"), row.names = 2131:2139, class = "data.frame") 

Xvalue = 1126 

#For comparing lagged or forward rows 
rowShift <- function(x, shiftLen = 1) { 
    r <- (1 + shiftLen):(length(x) + shiftLen) 
    r[r<1] <- NA 
    return(x[r]) } 

DATA$SignalBinary <- as.numeric(DATA$Close < Xvalue & rowShift(DATA$FOMCBinary, +1) > 0) 
DATA$SignalBinary <- c(sapply(1:(nrow(DATA)-1), function(n) { 
    if (is.na(DATA$SignalBinary[n+1])) return(NA) 
    if (DATA$SignalBinary[n+1]) return(0) 
    DATA$SignalBinary[n] 
}), tail(DATA$SignalBinary,1)) 
DATA 


anotherDATA <- structure(list(DateTime = structure(list(sec = c(0, 0, 0, 0, 0, 0, 0, 0, 0), min = c(30L, 15L, 0L, 45L, 30L, 15L, 0L, 45L,30L), 
    hour = c(15L, 15L, 15L, 14L, 14L, 14L, 14L, 13L, 13L),mday = c(27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L), 
    mon = c(0L,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), year = c(116L, 116L, 116L,116L, 116L, 116L, 116L, 116L, 116L), 
    wday = c(3L, 3L, 3L,3L, 3L, 3L, 3L, 3L, 3L), yday = c(26L, 26L, 26L, 26L, 26L,26L, 26L, 26L, 26L), 
    isdst = c(0L, 0L, 0L, 0L, 0L, 0L, 0L,0L, 0L), zone = c("EST", "EST", "EST", "EST", "EST", "EST","EST", "EST", "EST"), 
    gmtoff = c(NA_integer_, NA_integer_,NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_,NA_integer_, NA_integer_)), 
    .Names = c("sec", "min", "hour","mday", "mon", "year", "wday", "yday", "isdst", "zone", "gmtoff"), class = c("POSIXlt", "POSIXt")), 
    Close = c(1127.2, 1127.5,1126.9, 1128.3, 1125.4, 1122.7, 1122.8, 1117.3, 1116), 
    FOMCBinary = c(0,0, 0, 0, 0, 1, 1, 0, 0)), .Names = c("DateTime", "Close", "FOMCBinary"), row.names = 2131:2139, class = "data.frame") 

Xvalue = 1126 

#For comparing lagged or forward rows 
rowShift <- function(x, shiftLen = 1) { 
    r <- (1 + shiftLen):(length(x) + shiftLen) 
    r[r<1] <- NA 
    return(x[r]) } 

anotherDATA$SignalBinary <- as.numeric(anotherDATA$Close < Xvalue & rowShift(anotherDATA$FOMCBinary, +1) > 0) 
anotherDATA$SignalBinary <- c(sapply(1:(nrow(anotherDATA)-1), function(n) { 
    if (is.na(anotherDATA$SignalBinary[n+1])) return(NA) 
    if (anotherDATA$SignalBinary[n+1]) return(0) 
    anotherDATA$SignalBinary[n] 
}), tail(anotherDATA$SignalBinary,1)) 
anotherDATA