r - r 在绘制日内数据时如何从 x 轴中删除工作日的非工作时间(以及周末和节假日)
问题描述
在 R 中,我在 5 分钟绘制了一些盘中价格数据。间隔,因此需要修改 x 轴以删除市场关闭的时间段,即周一至周五下午 4 点至上午 9 点,节假日除外。
我使用包 bdscale 最接近实现这一点,它不是专门设计用于删除工作日的下班时间,但可以做到这一点。
这是一个可重复的示例,尽管它需要一个 alpha vantage API 密钥(它是免费的)。
library(tidyquant)
library(alphavantager)
library(bdscale)
library(scales)
this_ts <- "SPY"
av_api_key("YOUR_KEY_HERE")
df_ohlcv <- this_ts %>%
tq_get(get = "alphavantager", av_fun = "TIME_SERIES_INTRADAY", interval = "5min")
df_ohlcv$p <- rowSums(df_ohlcv[, c(3:5)]) / 3
df <- df_ohlcv[, c("timestamp", "p")]
gg <- ggplot(df, aes(x = timestamp, y = p))
gg <- gg + geom_line()
gg <- gg + scale_x_bd(business.dates = df$timestamp, labels = date_format("%a\n%b %d\n%H:%M"))
gg
如您所见,生成的图删除了下班后的时间段,但 x 轴标签却被弄乱了。此外,背景中的灰色面板很不稳定。也许使用 bdscale 以外的东西会更好?帮助表示赞赏。
编辑:
> dput(df)
structure(list(timestamp = structure(c(1563286500, 1563286800,
1563287100, 1563287400, 1563287700, 1563288000, 1563288300, 1563288600,
1563288900, 1563289200, 1563289500, 1563289800, 1563290100, 1563290400,
1563290700, 1563291000, 1563291300, 1563291600, 1563291900, 1563292200,
1563292500, 1563292800, 1563356100, 1563356400, 1563356700, 1563357000,
1563357300, 1563357600, 1563357900, 1563358200, 1563358500, 1563358800,
1563359100, 1563359400, 1563359700, 1563360000, 1563360300, 1563360600,
1563360900, 1563361200, 1563361500, 1563361800, 1563362100, 1563362400,
1563362700, 1563363000, 1563363300, 1563363600, 1563363900, 1563364200,
1563364500, 1563364800, 1563365100, 1563365400, 1563365700, 1563366000,
1563366300, 1563366600, 1563366900, 1563367200, 1563367500, 1563367800,
1563368100, 1563368400, 1563368700, 1563369000, 1563369300, 1563369600,
1563369900, 1563370200, 1563370500, 1563370800, 1563371100, 1563371400,
1563371700, 1563372000, 1563372300, 1563372600, 1563372900, 1563373200,
1563373500, 1563373800, 1563374100, 1563374400, 1563374700, 1563375000,
1563375300, 1563375600, 1563375900, 1563376200, 1563376500, 1563376800,
1563377100, 1563377400, 1563377700, 1563378000, 1563378300, 1563378600,
1563378900, 1563379200), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
p = c(299.738333333333, 299.628333333333, 299.616666666667,
299.633333333333, 299.556666666667, 299.658333333333, 299.805,
299.843333333333, 299.913333333333, 299.843333333333, 299.844,
299.935, 299.963333333333, 300.003333333333, 300.016666666667,
299.924333333333, 299.92, 299.985, 300.046666666667, 299.958333333333,
299.95, 299.846666666667, 299.77, 299.78, 299.753333333333,
299.563333333333, 299.626666666667, 299.598333333333, 299.585,
299.43, 299.256666666667, 299.1333, 299.13, 299.096666666667,
299.046633333333, 299.063333333333, 298.804333333333, 298.59,
298.45, 298.598333333333, 298.763333333333, 298.776333333333,
298.893333333333, 298.875, 298.915, 298.844966666667, 298.83,
298.86, 299.036666666667, 299.129033333333, 299.203333333333,
299.136633333333, 299.058333333333, 299.038333333333, 298.873,
298.856666666667, 298.8373, 298.846666666667, 298.863333333333,
298.938333333333, 298.970033333333, 298.88, 298.912266666667,
298.95, 298.903333333333, 298.871666666667, 298.86, 298.8,
298.805666666667, 298.843966666667, 298.886533333333, 298.9178,
299.028333333333, 299.015, 298.986666666667, 298.973333333333,
298.818466666667, 298.708166666667, 298.548333333333, 298.543333333333,
298.613333333333, 298.66, 298.716666666667, 298.753333333333,
298.7, 298.693333333333, 298.6067, 298.586, 298.388333333333,
298.458333333333, 298.613333333333, 298.6254, 298.45, 298.245,
298.335, 298.361666666667, 298.273333333333, 298.258333333333,
298.266666666667, 298.027566666667)), .Names = c("timestamp",
"p"), row.names = c(NA, -100L), class = c("tbl_df", "tbl", "data.frame"
))
解决方案
我不确定是否有一种简单的解决方案可以在不将比例转换为离散比例的情况下以您想要的方式更改休息时间。
这样做的缺点是你失去了灵活设置休息时间的能力scale_x_datetime
。为了解决这个问题,我给出了一些示例,说明如何通过更改数据框来设置一些方便的中断,如下例所示。我还将时间戳列转换为用于离散刻度的字符。
我假设,由于您正在获取市场时间的数据,因此市场时间已经由数据中的时间戳列定义。这样可以避免定义不包括假期等的自定义比例。
# convert to character column and set up handy columns for making breaks
df <- df %>%
mutate(timestamp_chr = as.character(df$timestamp),
day = lubridate::day(timestamp),
hour = lubridate::hour(timestamp),
minute = lubridate::minute(timestamp),
new_day = if_else(day != lag(day) | is.na(lag(day)), 1, 0))
df
# # A tibble: 100 x 7
# timestamp p day hour minute timestamp_chr new_day
# <dttm> <dbl> <int> <int> <int> <chr> <dbl>
# 1 2019-07-16 14:15:00 300. 16 14 15 2019-07-16 14:15:00 1
# 2 2019-07-16 14:20:00 300. 16 14 20 2019-07-16 14:20:00 0
# 3 2019-07-16 14:25:00 300. 16 14 25 2019-07-16 14:25:00 0
# 4 2019-07-16 14:30:00 300. 16 14 30 2019-07-16 14:30:00 0
# 5 2019-07-16 14:35:00 300. 16 14 35 2019-07-16 14:35:00 0
# 6 2019-07-16 14:40:00 300. 16 14 40 2019-07-16 14:40:00 0
# 7 2019-07-16 14:45:00 300. 16 14 45 2019-07-16 14:45:00 0
# 8 2019-07-16 14:50:00 300. 16 14 50 2019-07-16 14:50:00 0
# 9 2019-07-16 14:55:00 300. 16 14 55 2019-07-16 14:55:00 0
# 10 2019-07-16 15:00:00 300. 16 15 0 2019-07-16 15:00:00 0
# # … with 90 more rows
# breaks equally spaced
my_breaks <-df$timestamp_chr[seq.int(1,length(df$timestamp_chr) , by = 10)]
ggplot(df, aes(x = timestamp_chr, y = p, group = 1)) +
geom_line() +
scale_x_discrete(breaks = my_breaks) +
theme(axis.text.x = element_text(angle = 90))
在上面的示例中,我使用了等间距的中断,但您也可以指定,例如:
# breaks on the hour
my_breaks <- df[df$minute == 0,]$timestamp_chr
# breaks at start of each new day
my_breaks <- df[df$new_day == 1,]$timestamp_chr
推荐阅读
- python-2.7 - 使用 pythons kubernetes 库的 kubernetes 的 pod 的“容器启动”事件
- ios - 如何使用 tableview 重新加载以下视图控制器?
- javascript - How to Add two Select tags with Submit button to Jump to url URL
- r - detecting common characters in a list of strings, at specific positions
- powershell - PowerShell - 检查 .ini 文件,记录问题
- javascript - v-model 将动态添加的输入字段设置为 undefined
- c# - 如何从多个动态添加的 Select2 下拉列表中获取所选项目?
- android - 返回上一个片段给出空容器
- python - 有条件地根据另一列中的值填充熊猫中的空值
- c++ - C++ 类向量错误,表达式必须有指针类型