#' read string data from target dir and parse the string according to specified pattern
#'
#' @param dtaDir string
#' @param pattern string
#' @return data frame
#' @export
loadStr <- function(dtaDir,
pattern='R|X1|X2|time|xchange|ticker|price|total_Volume|BP1|BV1|SP1|SV1|OI|settle_Price1|Volume|BP2|BP3|BP4|BP5|BV2|BV3|BV4|BV5|SP2|SP3|SP4|SP5|SV2|SV3|SV4|SV5|limit_up|limit_dn|open|cum_High|cum_Low|close|OI1|cum_VWAP|totalAmount|Amount',
colClass=list(cha=c(1,4,5,6), int=c(8,10,12,13,15,20,21,22,23,28,29,30,31,38), dbl=c(7,9,11,14,16,17,18,19,24,25,26,27,32,33,34,35,36,37,39,40,41),logi=c(2,3)),
...)
{
colnms <- unlist(strsplit(pattern,'\\|'))
dta <- tryCatch(scan(dtaDir, what='', quiet=TRUE, sep = '~', ...), error=function(e)NULL)
if(length(dta))
{
dta <- do.call('rbind',strsplit(dta, '\\|'))
dta <- as.data.frame(dta, stringsAsFactors=FALSE)
n <- ncol(dta)
colClass <- lapply(colClass, function(x){
return(x[x<=n])
})
colnms <- head(colnms,n)
# set precision of variables
if(is.null(dta)) return(NULL) else {
if(length(colClass$int))
{
for(i in colClass$int[colClass$int<=ncol(dta)])
{
dta[,i] <- as.integer(dta[,i])
}
}
if(length(colClass$logi[colClass$logi<=ncol(dta)]))
{
for(i in colClass$logi)
{
dta[,i] <- as.logical(dta[,i])
}
}
if(length(colClass$dbl))
{
for(i in colClass$dbl[colClass$dbl<=ncol(dta)])
{
dta[,i] <- as.numeric(dta[,i])
}
}
}
# set colnames of dta
# dta <- dta[, 1:(ncol(dta)-1)]
# dta <- dta[, 1:n]
names(dta)[seq_along(colnms)] <- colnms#[1:n]
# dta$time <- sprintf('%s%s',ifelse(dta$time<10^8, '0',''),dta$time)
dta$time <- sprintf('%s:%s:%s.%s', substr(dta$time,1,2), substr(dta$time,3,4), substr(dta$time,5,6),substr(dta$time,7,9))
return(dta)
} else return(NULL)
}
#' update local data files(night market)
#'
#' keep local data files updated to the latest
#' @param tickers string vector. specify target tickers to save. if null, all existed tickers on save2path will be downloaded.
#' @param save2path string. specify target dir to save tick data to
#' @param shareDir string. specify the mapping driver of 'share', default 'Y:/'
#' @return NULL
#' @export
updateNightTick <- function(save2path='/home/yuanwei/data/night', shareDir=c('/mnt/futuredata/ZZFE/level2/stringl2/night','/mnt/futuredata/Dce/string/night','/mnt/futuredata/SHFE/string/night'), ...)
{
temp = sapply(shareDir, function(x)list.files(x,full=FALSE))
itemDict <- do.call('rbind', strsplit(unlist(temp), '_'))
itemDict = data.frame(rep(shareDir, lapply(temp, length)), itemDict, row.names = NULL, stringsAsFactors = FALSE)
f <- sprintf('%s/%s',itemDict[,1], paste(itemDict[,2], itemDict[,3], sep='_'))
if(length(f)==0) return(NULL)
for(i in seq_along(f))
{
dates <- substr(unlist(list.files(f[i],'[0-9\\-].txt$', full.names=FALSE)),1,10)
if(!dir.exists(sprintf('%s/%s/', save2path, itemDict[i, 2])))dir.create(sprintf('%s/%s/', save2path, itemDict[i, 2]))
dates <- setdiff(dates,gsub('.rda','',list.files((sprintf('%s/%s/', save2path, itemDict[i, 2])), full.names=FALSE)))
cat(sprintf('%s(%s)(%s ~ %s) to update',itemDict[i,2],length(dates), min(dates), max(dates)))
if(length(dates)==0) {
cat(' local data base is already the latest version.\n')
next
}
for(date in dates)
{
dta <- loadStr(dtaDir=sprintf('%s/%s.txt',f[i],date),...)
assign(itemDict[i,2], dta)
save(list=c(itemDict[i,2]), file=sprintf('%s/%s/%s.rda',save2path,itemDict[i,2],date))
cat('.')
}
cat('over!\n')
}
cat(sprintf('%s tickers under the folder<%s> are updated!\n', length(tickers), save2path))
return(invisible(NULL))
}
#' extract clock-wise bar from tick data
#'
#' generic function for extracting clock-wise bar(sec bar, minute bar, hour bar or even daily bar) from tick data.
#' @param dta data frame or matrix, with at least fields of date, time, price and volume optional.
#' @param start.point character. specify the start point of each bar in the format of 'hh:mm:ss', default '00:00:00'
#' @param len character. specify the length of each bar in the format of 'hh:mm:ss'. if larger than 2 hours('02:0:00), daily bar data is returned. default '00:01:00'.
#' @param timespan ascendingly ordered character vector. specify the normal trading time period for invalid data filter. default c('09:15:00', '11:29:59', '13:00:00', '15:14:59'), which is the case of stock index future data.
#' @param volume.save whether to keep the volume in return bar data. default TRUE.
#' @return A dataframe with the fileds of Date, Time, Open, High, Low, Close and Volume optional.
#' @seealso Tick2bar.vol, OHLC.plot
#' @export
Tick2bar.time <- function(dta, len = '00:01:00', timespan = NULL, volume.save = TRUE, start.point = '00:00:00')
{
# require('xts')
n <- length(timespan)/2
stopifnot(n%%1==0)
colnames(dta) <- tolower(colnames(dta))
start.point <- chron::times(start.point)
len <- chron::times(len)
if(nrow(dta)==0) return(NULL)
dta$ID <- 1:nrow(dta)
if(class(dta[,'time'])!='times') dta[,'time'] <- chron::times(dta[,'time'])
if(is.null(timespan))
{
if(grepl('IF',dta$symbol[1]))
timespan <- c('09:15:00','11:30:01','13:00:00','15:15:01')
else
timespan <- c('09:00:00','10:15:01','10:30:00','11:30:01','13:30:00','15:00:01')
timespan <- chron::times(timespan)
TS <- matrix(as.double(chron::times(timespan), digits=12), ncol=2, byrow=TRUE)
} else
{
timespan <- chron::times(timespan)
TS <- matrix(as.double(chron::times(timespan), digits=12), ncol=2, byrow=TRUE)
}
dta <- dta[rowSums(apply(TS, 1, function(x)dta[,'time']>=x[1] & dta[,'time']<x[2]))>0,]
if(nrow(dta)==0) return(NULL)
dtm <- as.numeric(format(as.double(dta[,'time']),digit=12))
if(len>='02:00:00')
{
TM <- range(timespan)
lab <- as.character(tail(TM,1))
} else
{
TM <- chron::times(c(unlist(apply(TS, 1, function(x)seq(from=x[1]+start.point, to=x[2], by=len)))))
lab <- as.character(TM + len - chron::times('00:00:01'))
TM <- c(TM, tail(TM, 1)+len)
}
inx <- as.character(cut(dtm, TM, right=FALSE, include.lowest=TRUE, ordered_result=FALSE,labels=lab))
if(volume.save)
{
res <- aggregate(1:nrow(dta), list(Time=inx), function(id){
with(dta[id, ], c(head(price,1),
max(price),
min(price),
tail(price,1),
mean(price*volume)/mean(volume),
tail(sp1,1),
tail(bp1,1),
sum(volume),
tail(ID,1)))})
res <- do.call('data.frame', list(unclass(res), stringsAsFactors=FALSE))
names(res) <- c('Time','Open','High','Low','Close','VWAP','SP1','BP1','Volume','tickID')
} else
{
res <- aggregate(1:nrow(dta), list(Time=inx), function(id){
with(dta[id, ], c(head(price,1),
max(price),
min(price),
tail(price,1),
tail(sp1,1),
tail(bp1,1),
tail(ID,1)))})
res <- do.call('data.frame',list(unclass(res), stringsAsFactors=FALSE))
names(res) <- c('Time','Open','High','Low','Close','SP1','BP1','tickID')
}
if('date' %in% colnames(dta)){
res <- data.frame(Symbol=dta$symbol[1], Time=lab, res[match(lab, res$Time),-(1)], row.names=NULL, stringsAsFactors=FALSE,check.rows=FALSE,check.names=FALSE)
} else{
res <- data.frame(Symbol=dta$symbol[1], Time=lab, res[match(lab, res$Time),-(1)], row.names=NULL, stringsAsFactors=FALSE,check.rows=FALSE,check.names=FALSE)
}
#res <- xts(res[,-(1:2)], as.POSIXlt(paste(res$Date,res$Time)))
return(res)
}
#' extract volume-wise bar from tick data
#'
#' generic function for extracting volume-wise bar from tick data.
#' @param dta data frame or matrix, with at least fields of date, time, price and volume optional. ORIGINAL tick data from data provider
#' @param unit integer. specify the unit of volume chunk as a bar. default 1200
#' @param timespan ascendingly ordered character vector. specify the normal trading time period for invalid data filter. default c('09:15:00', '11:29:59', '13:00:00', '15:14:59'), which is the case of stock index future data.
#' @return A dataframe with the fileds of Date, ID, Time, Open, High, Low, Close and Volume.
#' @seealso Tick2bar.time, OHLC.barplot
#' @export
Tick2barBy <- function(dta, By, unit = 1200, timespan =NULL)
{
n <- length(timespan)/2
stopifnot(n%%1==0)
colnames(dta) <- tolower(colnames(dta))
if(!is.null(timespan))
{
TS <- matrix(timespan, ncol=2, byrow=TRUE)
dta <- dta[rowSums(apply(TS, 1, function(x)dta[,'time']>=x[1] & dta[,'time']<=x[2]))>0, ]
}
vol.total <- By
if(tail(vol.total,1))
{
loc <- unclass(cut(vol.total, seq(vol.total[1]-unit/2, tail(vol.total,1)+unit/2, by=unit)))
from <- c(0, which(diff(loc)!=0))+1
to <- c(tail(from,-1)-1, length(vol.total))
res <- sapply(seq_along(from), function(i){
c(Open=dta[from[i],'price'],
High=max(dta[from[i]:to[i],'price']),
Low=min(dta[from[i]:to[i],'price']),
Close=dta[to[i],'price'],
VWAP=sum(dta[from[i]:to[i],'price']*dta[from[i]:to[i],'volume'])/sum(dta[from[i]:to[i],'volume']),
SP1=dta[to[i],'sp1'],
BP1=dta[to[i],'bp1']
)
})
res <- data.frame(Time=dta$time[to], t(res), tickID=to, row.names = NULL)
} else
{
res <- data.frame(Time=tail(dta[,'time'],1),Open=NA, High=NA, Low=NA, Close=NA, VWAP=NA, SP1=NA, BP1=NA, tickID=NA, row.names=NULL)
}
return(res)
}
#' load original data and reshape into time-bar
#'
#' load tick data from 'share' server and then reshape it into time-bar data
#' @param ticker string.
#' @param start string(YYYY-MM-DD) or date. specify the start date of bar data. If null, take the earliest as possible
#' @param end string(YYYY-MM-DD) or date. specify the end date of bar data. If null, take the latest as possible
#' @param localDtaPath string. specify local dir where the tick data(.rda) files are saved
#' @param ... arguments to be passed to <tick2bar.time>
#' @return A dataframe or NULL.
#' @export
loadBar <- function(ticker, start=NULL, end=NULL, localDtaPath, ...)
{
require(foreach)
dtadir <- sprintf('%s/%s/', localDtaPath, ticker)
filenms <- list.files(dtadir, '.rda$', full.names=FALSE)
dates <- substr(filenms, 1, 10)
if(!is.null(start)) dates <- dates[dates>=start]
if(!is.null(end)) dates <- dates[dates<=end]
filedir <- sprintf('%s/%s.rda', dtadir, dates)
if(length(dates)) cat(sprintf('Download %s (%s ~ %s)', ticker, min(dates), max(dates))) else cat('No data files found!')
res <- foreach(ff = filedir, .combine='rbind')%do%
{
load(ff)
if(is.null(get(ticker)))
{
res0 <- NULL
} else res0 <- Tick2bar.time(get(ticker), ...)
cat('.')
return(res0)
}
cat('Over!\n')
return(res)
}
#' plot american candlestick chart
#'
#' @param OHLC data frame, with at least fields of O-H-L-C, e.g. return value of Tick2bar.* function
#' @param Time character vector, specify the time stamp of each bar. if NULL, try to find time field from OHLC. default NULL
#' @param up.col character, specify colour for up-ward bars
#' @param dn.col character, specify colour for down-ward bars
#' @param main string
#' @param sub string
#' @param lwd integer
#' @param mar integer vector
#' @param cex.axis numeric value
#' @param tcl integer
#' @param par.recover logical, whether to recover par settings after the plot. default TRUE
#' @param ... further arguments to be passed to <par>
#' @return NULL
#' @seealso Tick2bar.time, Tick2bar.vol
#' @export
OHLC.plot <- function(OHLC, Time=NULL, up.col='red2', dn.col='green4', main='', sub='', ylab='',lwd=1, mar=c(4,3,3,1), cex.axis=.8, tcl=-.1, axes=list(x=TRUE, y=TRUE), par.recover=TRUE, between=NULL, type='Japanese',...)
{
type <- match.arg(type,c('American', 'Japanese'))
if(length(Time)>0)
{
stopifnot(length(Time)==nrow(OHLC))
} else if(any(grepl('time', names(OHLC), ignore.case=TRUE))) Time = OHLC$Time else Time = 1:nrow(OHLC)
old.par <- par(mar=mar, cex.axis=cex.axis,tcl=tcl,...)
n.bar <- nrow(OHLC)
if(is.null(between)) between <- 1/4
att <- round(seq(1, n.bar, len=20),0)
plot(1,1,xlim=c(1,n.bar),ylim=range(OHLC[,c('High','Low')],na.rm=TRUE),type='n',main=main,sub=sub,xlab='',ylab=ylab, axes=FALSE)
if(axes$x) {
abline(v=att, col='grey90', lty='dotted')
axis(1,att,labels=as.character(Time)[att])
}
if(axes$y) {
axis(2,las=2)
}
box()
hl <- c(OHLC[1,'Close'] > OHLC[1,'Open'],diff(OHLC[,'Close']) >= 0)
if(type=='American')
{
segments(1:nrow(OHLC),OHLC[,'High'],1:nrow(OHLC),OHLC[,'Low'],col=c(dn.col,up.col)[hl/2+1.5],lwd=lwd)
segments(1:nrow(OHLC)-between,OHLC[,'Open'], 1:nrow(OHLC),OHLC[,'Open'],col=c(dn.col,up.col)[hl/2+1.5],lwd=lwd)
segments(1:nrow(OHLC),OHLC[,'Close'], 1:nrow(OHLC)+between,OHLC[,'Close'],col=c(dn.col,up.col)[hl/2+1.5],lwd=lwd)
} else if(type=='Japanese')
{
bw <- c(-between, between,between, -between)
col <- c(dn.col,up.col)[hl/2+1.5]
for(i in 1:n.bar)
{
polygon(x=i+bw,y=rep(OHLC[i,c('Open','Close')],each=2),border=col[i], col=col[i])
}
segments(1:n.bar,OHLC$Low, 1:n.bar,OHLC$High,col=col,lwd=1)
}
if(par.recover) par(old.par)
return(invisible(list(up.col=up.col, dn.col=dn.col, lwd=lwd, mar=mar, cex.axis=cex.axis, tcl=tcl, between=between,type=type)))
}
#' zoom in the details of plot
#'
#' zoom in specified window of plot with your cursor
#' @param dta data frame/matrix. dta used to generate a snapshot
#' @param myplot string. user defined plot function name(return y variable from the key plot)
#' @seealso play
#' @details the arguments of function myplot include 2 parts: 1) datafeed(dta) of plot 2)other optional arguments(...). excpet plotting, myplot should return y-variable of the key part of plot, with optional attribute of note to cat.
#' @export
zoom <- function(dta, myplot, ...){
myplot <- match.fun(myplot)
n <- NROW(dta)
if(is.null(time)) time <- 1:n
sigLoc <- list('sig'%in%names(dta))
if(sigLoc[[1]]) {
# dta$sig <- sign(dta$sig)
sigLoc[[2]] <- which(!is.na(tail(dta,1)$sig))
}
lastView <- NULL
lastView[[1]] <- timespan <- c(1, n)
X11(title='<zoom mode>') #windows()
i <- 0
cat('zoom mode ready:
\t double click two ends of window to <zoom in>
\t double click left margin to <quit>
\t double click right margin to <backward view>
\t double click bottom margin back to <birdView> ...\n') # \t double click top margin to <forward view>
while(TRUE)
{
cat(sprintf('(%i ~ %i)\n',timespan[1],timespan[2]))
dev.hold()
# if(timespan[2]==n){
# ans <- myplot(dta, ...)
# } else {
ans <- myplot(dta[timespan[1]:timespan[2],], ...)
# if(!is.null(highlight)){
# highlight <- NULL
# }
# }
dev.flush()
if('note' %in% names(attributes(ans)) && (!is.na(attr(ans,'note'))) && nchar(attr(ans,'note'))) cat(sprintf('* %s\n',attr(ans,'note')))
# ylim <- min(dta[timespan[1]:timespan[2],target])
ylim <- range(ans,na.rm=TRUE)
loc <- locator(2)
if(!is.null(loc)){
if(max(loc$x)<1){
dev.off()
break
} else if(min(loc$x)>diff(timespan)+1){
if(i>1){
timespan <- lastView[[i]]
i <- i-1
} else {
i <- 0
lastView <- NULL
timespan <- c(1,n)
}
} else if(max(loc$y)<ylim[1]){
i <- i+1
lastView[[i]] <- timespan
timespan <- c(1,n)
} else
# if(min(loc$y)>ylim[2]){
# if(!is.null(lastView) && i<=length(lastView)){
# i <- i+1
# timespan <- lastView[[i]]
# }
# } else
{
i <- i+1
lastView[[i]] <- timespan
loc$x <- pmax(1, pmin(loc$x,diff(timespan)+1))
timespan <- seq(max(1,timespan[1]-1),min(n,timespan[2]+1))[range(round(loc$x))]
}
}
}
cat(' quit <zoom> mode!\n')
return(invisible(timespan[1]:timespan[2]))
}
#' animation play
#'
#' play animation step by step
#' @param dta data.frame/matrix. dta used to generate a figure
#' @param myplot string. user defined plot funciton name
#' @param hold integer. number of seconds to hold each snapshot
#' @param window integer. length of window of each snapshot
#' @param stepwise integer/vector/NULL. specify the track/steps of play
#'
#' @seealso zoom
#' @export
play <- function(dta, myplot, hold=.5, window=NA, cumView=FALSE, stepwise=NULL, ...)
{
stopifnot(!is.null(dim(dta)))
window <- ifelse(is.na(window), NROW(dta), window)
myplot <- match.fun(myplot)
n <- NROW(dta)
save <- FALSE
if(save)
{ ## not work properly...
require('animation')
saveGIF(
for(i in stepwise)
{
# dev.hold()
myplot(dta[max(1,i-window+1):i,],...)
# dev.flush()
}, movie.name='~/animation.gif', interval=hold
)
} else
{
cat('playing...\n press <Alt> to suspend and once again to continue\n')
if(is.null(stepwise)) stepwise <- 1:n else stepwise <- stepwise[stepwise>=1 & stepwise<=n]
x11(title='<play mode> press ESC to quit')
for(i in stepwise)
{
dev.hold()
myplot(dta[ifelse(cumView, 1, max(1,i-window+1)):i,],...)
dev.flush()
Sys.sleep(hold)
}
}
}
#' example sub-function of zoom
#'
#' show an example function of 'myplot' which is a parameter of zoom function. here we test to zoom in the tick data - order book.
#'
#' @seealso zoom
#' @export
zoom.myplot <- function(dta, n)
{
stopifnot(all(c('Time','Price','BV1','SV1','BP1','SP1','Volume')%in%colnames(dta)))
if(nrow(dta)==n)
{
layout(matrix(1))
plot(ifelse(dta[,'Price']<.001, NA, dta[,'Price']),type='l',col='grey',ylab='',pch=20,cex=.5)
if('sig'%in%names(dta))
{
loc <- which(!is.na(dta$sig))
points(loc, ifelse(dta$sig[loc]>0, dta$SP1[loc], dta$BP1[loc]),col=(3:2)[dta$sig[loc]/2+1.5],pch=20,lwd=2)
}
} else
{
layout(matrix(1:2))
par(mar=c(0,3,2,2),cex.axis=.7)
matplot(dta[,c('Volume','BV1','SV1')],type='l',lty=1,col=c('grey','red','green'),lwd=2,axes=FALSE,ylab='')
axis(2,las=2)
box()
grid()
par(mar=c(2,3,0,2))
matplot(dta[,c('BP1','SP1')],col=2:3,lty=1,type='l',ylab='',axes=FALSE,ylim=range(dta[,c('BP1','SP1')][dta[,c('BP1','SP1')]>.001]))
points(ifelse(dta[, 'Price']>.001, dta[, 'Price'], NA), col='grey', pch=20, cex=.7)
axis(1)
axis(2,las=2)
box()
points(ifelse(dta[,'Volume']>0, dta[,'Price'], NA),col='grey', pch=20, cex=.5)
if('sig'%in%names(dta)) points(ifelse(dta$sig>0,dta$SP1,dta$BP1),col=(3:2)[dta$sig/2+1.5],pch=20,lwd=2)
box()
grid()
}
ans <- dta$BP1
attr(ans,'note') <- sprintf('%s~%s', dta$Time[1],tail(dta$Time,1))
return(ans)
}
#' image plot with matrix
#'
#' @param x matrix
#' @return NULL
#' @export
myImagePlot <- function(x, ...){
min <- min(x)
max <- max(x)
yLabels <- rownames(x)
xLabels <- colnames(x)
title <-c()
# check for additional function arguments
if( length(list(...)) ){
Lst <- list(...)
if( !is.null(Lst$zlim) ){
min <- Lst$zlim[1]
max <- Lst$zlim[2]
}
if( !is.null(Lst$yLabels) ){
yLabels <- c(Lst$yLabels)
}
if( !is.null(Lst$xLabels) ){
xLabels <- c(Lst$xLabels)
}
if( !is.null(Lst$title) ){
title <- Lst$title
}
}
# check for null values
if( is.null(xLabels) ){
xLabels <- c(1:ncol(x))
}
if( is.null(yLabels) ){
yLabels <- c(1:nrow(x))
}
layout(matrix(data=c(1,2), nrow=1, ncol=2), widths=c(5,1), heights=c(1,1))
# Red and green range from 0 to 1 while Blue ranges from 1 to 0
ColorRamp <- rgb( seq(0,1,length=256), # Red
seq(0,1,length=256), # Green
seq(1,0,length=256)) # Blue
ColorLevels <- seq(min, max, length=length(ColorRamp))
# Reverse Y axis
reverse <- nrow(x) : 1
yLabels <- yLabels[reverse]
x <- x[reverse,]
# Data Map
par(mar = c(3,5,2.5,2))
image(1:length(xLabels), 1:length(yLabels), t(x), col=ColorRamp, xlab="",
ylab="", axes=FALSE, zlim=c(min,max))
if( !is.null(title) ){
title(main=title)
}
axis(BELOW<-1, at=1:length(xLabels), labels=xLabels, cex.axis=0.7)
axis(LEFT <-2, at=1:length(yLabels), labels=yLabels, las= HORIZONTAL<-1,
cex.axis=0.7)
# Color Scale
par(mar = c(3,2.5,2.5,2), cex=.7)
image(1, ColorLevels,
matrix(data=ColorLevels, ncol=length(ColorLevels),nrow=1),
col=ColorRamp,
xlab="",ylab="",
xaxt="n")
layout(1)
}
#' ordbook building with pv info
#'
#' @param p data.frame/matrix price, [BS]1,[BS]2,[BS]3,[BS]4,...
#' @param v data.frame/maxtirx volume, mapping with price
#' @param tick numeric/integer minimum tick
#' @param bsFlag integer 1: buy, -1: sell
#' @return array ordbook
#' @export
pv2ordbook <- function(p, v, tick, bsFlag, locf=TRUE)
{
# bsFlag=1, bpv, b1,b2,b3,...
# bsFlag=-1, spv, s1,s2,s3...
nr <- nrow(p)
nc <- ncol(p)
stopifnot(nc==ncol(v) && nr==nrow(v))
p <- as.matrix(p)
p <- ifelse(p<.0001, NA, p)
v <- as.matrix(v)
prng <- range(p, na.rm = TRUE)
if(any(is.na(prng))) return(NULL)
pgrid <- seq(prng[1], prng[2], by=tick)
npg <- length(pgrid)
ord <- array(NA, dim = c(nr, npg), dimnames = list(NULL, pgrid))
l <- (p-prng[1])/tick+1
storage.mode(l) <- 'integer'
l <- 1:nr+(l-1)*nr
l1 <- l[,1]
l2 <- l[,nc]
ord[l[!is.na(l)]] <- v[!is.na(l)]
l0 <- 1:nr+(matrix(1:npg, byrow=T, ncol=npg, nrow=nr)-1)*nr
ord[(l0-l1)*bsFlag>0] <- 0
ord[is.na(ord) & (l0-l2)*bsFlag>0] <- 0
if(locf) ord <- na.locf(ord, na.rm=F)
attr(ord, 'loc') <- l1
attr(ord, 'I') <- l0
return(ord)
}
#' change time to integer
#'
#' @param time hh:mm:ss:mmm...
#' @return vector
#' @export
time2int <- function(tt)
{
tt <- do.call('rbind', strsplit(tt, '(:)|(\\.)'))
storage.mode(tt) <- 'integer'
tt[,4] <- round(tt[,4]*10^-6)
return(tt%*%c(3600000000, 60000000, 1000000, 1))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.