Commit 2dafbe7d authored by Enrico Schumann's avatar Enrico Schumann

Version: 0.4-7

ts_table: attribute 'timestamp' is now the actual
datetime vector, not its numeric representation (this
reverts some changes introduced with ChangeLog entry of
2016-12-09)
parent a0b34c31
2017-05-22 Enrico Schumann <es@enricoschumann.net>
* DESCRIPTION (Version): 0.4-7
* R/functions.R (ts_table): attribute
'timestamp' is now the actual datetime vector,
not its numeric representation (this reverts
some changes introduced with ChangeLog entry
of 2016-12-09)
* R/functions.R (ts_table): explicitly unname
'x' (i.e. drop column and row names)
2017-05-16 Enrico Schumann <es@enricoschumann.net>
* R/functions.R (write_ts_table): have empty
files written (such files will only contain one
line, the headers)
* inst/unitTests/ut_write_read.R
(test.write_ts_table): add checks for writing
an empty file
2017-05-13 Enrico Schumann <es@enricoschumann.net>
* DESCRIPTION (Version): Version: 0.4-6
* DESCRIPTION (Version): 0.4-6
2017-05-10 Enrico Schumann <es@enricoschumann.net>
* R/functions.R (read_ts_tables): safeguard for
empty files
......
Package: tsdb
Type: Package
Title: Terribly-Simple Data Base for Time Series
Version: 0.4-6
Date: 2017-05-13
Version: 0.4-7
Date: 2017-05-22
Maintainer: Enrico Schumann <es@enricoschumann.net>
Authors@R: person("Enrico", "Schumann",
role = c("aut", "cre"),
......
......@@ -61,18 +61,25 @@ write_ts_table <- function(x, dir, file,
save.scipen <- options(scipen = 1e5)
on.exit(options(scipen = save.scipen))
timestamp <- .timestamp(x)
timestamp <- ttime(.timestamp(x))
columns <- .columns(x)
backend <- tolower(backend)
ans <- dim(x)[1L] ## a ts_table is always a matrix
if (ans == 0L)
return(invisible(0L))
if (backend == "csv") {
dfile <- if (missing(dir))
file
else
file.path(dir, file)
if (ans == 0L) {
if (!file.exists(dfile))
write.table(as.matrix(data.frame(timestamp, unclass(x))),
file = dfile,
row.names = FALSE,
col.names = c("timestamp", columns),
sep = ",")
return(invisible(0L))
}
if (add) {
in_db <- read_ts_tables(file, dir, drop.weekends = FALSE)
if (any(in_db$columns != columns))
......@@ -81,9 +88,9 @@ write_ts_table <- function(x, dir, file,
ans <- 0
if (any(new)) {
ans <- sum(new)
timestamp <- c(ttime(in_db$timestamp),
timestamp <- c(ttime(in_db$timestamp),
timestamp[new])
x <- rbind(in_db$data, x[new, , drop = FALSE])
x <- rbind(in_db$data, x[new, ,drop = FALSE])
if (is.unsorted(timestamp)) {
ii <- order(timestamp)
timestamp <- timestamp[ii]
......@@ -161,7 +168,8 @@ read_ts_tables <- function(file, dir, t.type = "guess",
if (length(samp) == 2L) {
tmp <- as.numeric(
strsplit(samp[[2]], ",", fixed = TRUE)[[1L]][[1L]])
t.type <- if (tmp < 30000) "Date" else "POSIXct"
t.type <- if (tmp < 43200) ## 86400/2
"Date" else "POSIXct"
} else
t.type <- "Date"
}
......@@ -293,7 +301,7 @@ file_info <- function(dir, file) {
stringsAsFactors = FALSE)
for (i in seq_len(nf)) {
fi <- read_ts_tables(dfile[i])
fi <- try(read_ts_tables(dfile[i]), silent = TRUE)
res[["min_timestamp"]][i] <- suppressWarnings(min(fi$timestamp))
res[["max_timestamp"]][i] <- suppressWarnings(max(fi$timestamp))
}
......@@ -330,6 +338,7 @@ ts_table <- function(data, timestamp, columns) {
ans <- as.matrix(data)
if (missing(columns))
columns <- colnames(ans)
ans <- unname(ans)
if (is.null(columns))
stop("no column names, and ", sQuote("columns"), " not provided")
if (ncol(ans) != length(columns))
......@@ -339,7 +348,7 @@ ts_table <- function(data, timestamp, columns) {
timestamp <- timestamp[ii]
ans <- ans[ii, ,drop = FALSE]
}
attr(ans, "timestamp") <- ttime(timestamp)
attr(ans, "timestamp") <- timestamp
attr(ans, "t.type") <- t.type
attr(ans, "columns") <- columns
class(ans) <- "ts_table"
......@@ -360,9 +369,7 @@ as.ts_table.zoo <- function(x, columns, ...) {
}
as.zoo.ts_table <- function(x, ...) {
ans <- zoo(unname(as.matrix(x)),
ttime(.timestamp(x),
from = "numeric", to = attr(x, "t.type")))
ans <- zoo(unname(as.matrix(x)), .timestamp(x))
colnames(ans) <- .columns(x)
ans
}
......@@ -396,18 +403,23 @@ as.matrix.ts_table <- function(x, ...) {
}
print.ts_table <- function(x, ...) {
tmp <- ttime(.timestamp(x),
from = "numeric", to = attr(x, "t.type"))
tmp <- .timestamp(x)
from_to <- if (length(tmp))
range(tmp)
else
c(NA, NA)
cat(nrow(x), " rows [",
as.character(from_to[[1L]]), " -> ",
as.character(from_to[[2]]),
"]: ",
paste(attr(x, "columns"), collapse = ", "),
"\n", sep = "")
if (nrow(x))
cat(nrow(x), " rows [",
as.character(from_to[[1L]]), " -> ",
as.character(from_to[[2]]),
"]: ",
paste(attr(x, "columns"), collapse = ", "),
"\n", sep = "")
else
cat(nrow(x), " rows : ",
paste(attr(x, "columns"), collapse = ", "),
"\n", sep = "")
invisible(x)
}
......@@ -420,6 +420,14 @@ In read_ts_tables(c("example1", "example2"), dir = "~/tsdb/daily", :
* How tsdb works
** ts_tables
tsdb works with /time-series tables/ (=ts_tables=). These are
numeric matrices, so there is always a =dim= attribute. Attached to
this matrix are several attributes:
- timestamp :: the numeric representation of the timestamp
** The file format
tsdb can store and load time-series data. The format it
......
......@@ -3,22 +3,35 @@
test.ts_table <- function() {
require("zoo")
x <- ts_table(11:15, as.Date("2016-1-1")-5:1, "close")
y <- ts_table(11:15, as.Date("2016-1-1")-5:1, "close")
checkEquals(x,
checkEquals(y,
structure(11:15,
.Dim = c(5L, 1L),
timestamp = c(16796, 16797, 16798, 16799, 16800),
timestamp = structure(c(16796, 16797, 16798, 16799, 16800),
class = "Date"),
t.type = "Date",
columns = "close",
class = "ts_table"))
tmp <- as.matrix(11:15); colnames(tmp) <- "close"
checkEquals(as.zoo(x),
checkEquals(as.zoo(y),
zoo(tmp, as.Date("2016-1-1")-5:1))
checkEquals(as.ts_table(as.zoo(x)), x)
checkEquals(as.ts_table(as.zoo(y)), y)
## check unnaming
x <- as.matrix(11:15)
colnames(x) <- "test_name"
y <- ts_table(x, as.Date("2016-1-1")-5:1, "close")
checkEquals(y,
structure(11:15,
.Dim = c(5L, 1L),
timestamp = structure(c(16796, 16797, 16798, 16799, 16800),
class = "Date"),
t.type = "Date",
columns = "close",
class = "ts_table"))
## intraday
y <- ts_table(11:15,
......@@ -26,14 +39,15 @@ test.ts_table <- function() {
"close")
checkEquals(y,
structure(11:15, .Dim = c(5L, 1L),
timestamp = c(1451642400, 1451642401,
1451642402, 1451642403,
1451642404),
timestamp = structure(c(1451642400, 1451642401,
1451642402, 1451642403,
1451642404),
class = c("POSIXct", "POSIXt")),
t.type = "POSIXct",
columns = "close",
class = "ts_table"))
}
test.read_ts_tables <- function() {
......@@ -75,14 +89,14 @@ test.read_ts_tables <- function() {
test.write_ts_table <- function() {
## require(tsdb);require(RUnit)
## require(tsdb);require(RUnit)
dir <- tempdir()
x <- ts_table(data = 11:15,
timestamp = as.Date("2016-1-1") + 1:5,
columns = "X")
ans <- write_ts_table(x, dir, "X")
message(dir, " ", ans, " ", nrow(x))
## message(dir, " ", ans, " ", nrow(x))
checkEquals(ans, nrow(x))
read_ts_tables("X", dir)
......@@ -97,6 +111,7 @@ test.write_ts_table <- function() {
ans <- write_ts_table(x, dir, "X", add = TRUE)
checkEquals(ans, 0)
## add a single new data point
x <- ts_table(data = 1,
timestamp = as.Date("2015-1-1"),
......@@ -111,4 +126,13 @@ test.write_ts_table <- function() {
ans <- write_ts_table(x, dir, "X")
checkEquals(ans, 0)
## write an empty file
x <- ts_table(numeric(0),
timestamp = Sys.Date()[0],
columns = "TEST")
ans <- write_ts_table(x, dir, "EMPTY_FILE")
checkEquals(ans, 0)
checkTrue(file.exists(file.path(dir, "EMPTY_FILE")))
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment