使用动态名称记录条件为真时的变量值
Posted
技术标签:
【中文标题】使用动态名称记录条件为真时的变量值【英文标题】:Record variable value when condition true with dynamic name 【发布时间】:2016-08-17 23:09:41 【问题描述】:我有 9x2 数据帧 DATS,每 15 分钟采样一次价格和 POSIXct 日期时间戳。以及带有最近 FOMC 事件日期的 FOMCDATES 日期列表。然后,我将 POSIXct 日期时间戳拆分为单独的日期和时间列。然后,每当 DATS 中的日期包含在 FOMCDATES 中并且时间为 14:30 时,我将 FOMCBinary 列添加到包含 1 的 DATS(编辑:FOMC 为 14:00,错误地使用了 14:30 - 示例仍然有效)。
我想在一个单独的变量中记录事件发生之前的关闭。变量的名称应基于事件的日期。在手头的情况下,结果应该是:PreEvent-2016-01-27 = 1122.7。请注意,这实际上会在包含数十个日期的大样本中运行,并且时间可能不是 14:30(例如,如果查看 NFP 而不是 FOMC)。
DATS <- 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)), .Names = c("DateTime","Close"), row.names = 2131:2139, class = "data.frame")
FOMCDATES <- structure(c(16785, 16827, 16876), class = "Date")
DATS$Time <- strftime(DATS$DateTime, format="%H:%M:%S")
DATS$Date <- as.Date(DATS$DateTime)
DATS$FOMCBinary <- ifelse( DATS$Time == "14:30:00" & DATS$Date %in% FOMCDATES, 1, 0)
#Output for FOMCDATES:
[1] 2015-12-16 2016-01-27 2016-03-16
#Output for DATS after calculations performed:
DateTime Close Time Date FOMCBinary
2131 2016-01-27 15:30:00 1127.2 15:30:00 2016-01-27 0
2132 2016-01-27 15:15:00 1127.5 15:15:00 2016-01-27 0
2133 2016-01-27 15:00:00 1126.9 15:00:00 2016-01-27 0
2134 2016-01-27 14:45:00 1128.3 14:45:00 2016-01-27 0
2135 2016-01-27 14:30:00 1125.4 14:30:00 2016-01-27 1
2136 2016-01-27 14:15:00 1122.7 14:15:00 2016-01-27 0
2137 2016-01-27 14:00:00 1122.8 14:00:00 2016-01-27 0
2138 2016-01-27 13:45:00 1117.3 13:45:00 2016-01-27 0
2139 2016-01-27 13:30:00 1116.0 13:30:00 2016-01-27 0
我的尝试结果是一个向量而不是单个值,并且变量名不是动态的。
#My failed attempt
#Define rowShift function
rowShift <- function(x, shiftLen = 1L)
r <- (1L + shiftLen):(length(x) + shiftLen)
r[r<1] <- NA
return(x[r])
PreEventLevel <- ifelse(DATS$FOMCBinary > 0, rowShift(DATS$Close, +1), 0)
如何做到这一点? 非常感谢!
【问题讨论】:
一个我错过的功能。谢谢你的提问。将编辑! Mmh 生成具有动态名称的变量不是很好的做法...您不能简单地使用列表作为变量的容器吗? 我可以而且事实上我需要,因为我需要创建一个仅包含最后一个 PreEventLevel 的 PreEventLevel 变量(例如,PreEventLevel = 1122.7,直到下个月新的 FOMC 发生)。也未能做到这一点,但想在一个单独的问题中提出。动态名称的目的是能够将每个 FOMC 事件的水平记录在一个单独的变量中。也许这不是最有效的实现方式,向量会更好。 【参考方案1】:在全局环境中使用动态名称创建变量不是一个好习惯...我宁愿使用列表作为值的容器,例如:
# get the indexes where FOMCBinary > 0
oneIdxs <- which(DATS$FOMCBinary > 0)
# get the close values using indexes on the shifted vector and put the values in a list
PreEventLevel <- as.list(rowShift(DATS$Close,1)[oneIdxs])
# set the dates as names of the element in the list
names(PreEventLevel) <- DATS$Date[oneIdxs]
> PreEventLevel
$`2016-01-27`
[1] 1122.7
# now you can access to values using:
# PreEventLevel[["2016-01-27"]]
# or
# PreEventLevel$`2016-01-27`
请注意,您也可以简单地创建一个带有名称而不是列表的向量(只需删除as.list
),PreEventLevel
将是:
> PreEventLevel
2016-01-27
1122.7
# you can access to values using PreEventLevel["2016-01-27"]
【讨论】:
@Gracos:没问题,添加了注释说明在这种情况下列表不是绝对必要的,您也可以使用命名向量;)以上是关于使用动态名称记录条件为真时的变量值的主要内容,如果未能解决你的问题,请参考以下文章