library(oce)
pairs.plot <- function(x, which=2:3, cex=par("cex"))
{
pairs(x$bp[which])
}
ts.plot <- function(t, x, ylab="", cex=par("cex"), tlim=range(t, na.rm=TRUE),
show.stats=TRUE, show.lm=FALSE, show.spline=TRUE,
green, orange, red)
{
if (!is.null(t) && !is.null(x)) {
oce::oce.plot.ts(t, x, type='n', xlab="", ylab=ylab, xlim=tlim)
if (show.lm) {
t0 <- as.numeric(t) - as.numeric(t[1]) # otherwise lm is poor
m <- lm(x ~ t0 + I(t0^2) + I(t0^3) + I(t0^4))
tt <- seq(min(t0), max(t0), length.out=100)
pp.ci <- predict(m, newdata=list(t0=tt), interval="confidence")
lines(as.POSIXct(tt+t[1]), pp.ci[,1], col='black', lwd=2)
lines(as.POSIXct(tt+t[1]), pp.ci[,2], col='gray')
lines(as.POSIXct(tt+t[1]), pp.ci[,3], col='gray')
}
if (show.spline) {
t0 <- as.numeric(t) - as.numeric(t[1])
if (length(t0) > 10) {
df <- max(2, diff(range(t0, na.rm=TRUE)) / 86400 / 30)
m <- smooth.spline(x ~ t0, df = df) # one df per month
tt <- seq(min(t0), max(t0), length.out=100)
pred <- predict(m, tt)$y
lines(as.POSIXct(tt+t[1]), pred, col='pink', lwd=3)
}
}
if (!missing(red) && !missing(orange) && !missing(green)) {
col.green <- rgb(0,1,0)
col.orange <- rgb(1,1,0)
col.red <- rgb(1,0,0)
col <- ifelse(x < green[1], "transparent",
ifelse(x <= green[2], col.green,
ifelse(x < orange[2], col.orange,
ifelse(x < red[2], col.red,
"black"))))
} else col <- rep("transparent", length(x))
points(t, x, bg=col, col="black", pch=21, cex=cex)
if (show.stats) {
m <- sprintf("%.0f", mean(x))
sd <- sprintf("%.0f", sd(x))
mtext(substitute(m %+-% sd, list(m=m, sd=sd)), side=4, cex=cex)
}
}
}
clock.plot <- function(t, x, label,
R, R.col="gray", R.lty="solid", R.lwd=0.5*par("lwd"),
lwd.axis=0.5*par("lwd"),
col.axis=gray(.2),
cex=par("cex"),
green, orange, red,
show.mean=TRUE)
{
ring <- function(R=1, col="gray", lty="dotted", lwd=0.5*par("lwd"))
{
i <- seq(0, 2*pi, length.out=360)
for (rval in R)
lines(rval * sin(i), rval * cos(i), col=col, lty=lty, lwd=lwd)
}
if (length(x) != length(t)) stop("lengths of t and x do not match")
tl <- as.POSIXlt(t)
hour <- tl$hour + (tl$min + tl$sec / 60) / 60
hour.angle <- pi + hour / 24 * 2 * pi
s <- sin(hour.angle)
c <- cos(hour.angle)
max.x <- max(x)
lim <- max(x) * c(-1, 1) * 1.04
plot(x * s, x * c, asp=1, xlab="", ylab="", xlim=lim, ylim=lim, axes=FALSE, type='n')
w <- -max.x / 25
if (!missing(green)) {
polygon(c(-green[1], -green[1], -green[2], -green[2]),
c(0, w, w, 0), col="limegreen", border="limegreen")
}
if (!missing(orange)) {
polygon(c(-orange[1], -orange[1], -orange[2], -orange[2]),
c(0, w, w, 0), col="orange", border="orange")
}
if (!missing(red)) {
polygon(c(-red[1], -red[1], -red[2], -red[2]),
c(0, w, w, 0), col="red", border="red")
}
at <- pretty(c(0,x), n=10)
axis(side=1, at=-at, labels=at, pos=0, cex.axis=0.9*cex, col=col.axis, col.axis=col.axis, mgp=c(1,1/4,0), tcl=-0.3)
box()
if (FALSE) {
for (r in abs(at))
ring(r, col=col.axis, lty="solid", lwd=0.5*par("lwd"))
}
if (!missing(R)) {
lR <- length(R)
lcol <- length(R.col)
llty <- length(R.lty)
llwd <- length(R.lwd)
if (lcol < lR) R.col <- c(R.col, rep(R.col[1], lR-lcol))
if (llwd < lR) R.lwd <- c(R.lwd, rep(R.lwd[1], lR-llwd))
if (llty < lR) R.lty <- c(R.lty, rep(R.lty[1], lR-llty))
for (i in 1:lR)
ring(R[i], col=R.col[i], lwd=R.lwd[i], lty=R.lty[i])
}
if (show.mean) {
xmean <- mean(x)
ring(xmean, col=col.axis, lty="solid")
}
## axes
abline(h=0, lty="solid", col=col.axis, lwd=lwd.axis)
abline(v=0, lty="solid", col=col.axis, lwd=lwd.axis)
mtext(side=1, "Midnight", cex=4/5*cex, col=col.axis)
mtext(side=2, "6 AM", cex=4/5*cex, col=col.axis)
mtext(side=3, "Noon", cex=4/5*cex, col=col.axis)
mtext(side=4, "6 PM", cex=4/5*cex, col=col.axis)
if (!missing(label))
mtext(side=1, label, line=-1, cex=cex, adj=0)
if (!missing(red) && !missing(orange) && !missing(green)) {
col.green <- rgb(0.3, 1.0, 0.3, alpha=0.3)
col.orange <- rgb(1.0, 1.0, 0.3, alpha=0.3)
col.red <- rgb(1.0, 0.3, 0.3, alpha=0.3)
col <- ifelse(x < green[1], "transparent",
ifelse(x <= green[2], col.green,
ifelse(x < orange[2], col.orange,
ifelse(x < red[2], col.red,
"black"))))
} else col <- rgb(.1, .1, .1, alpha=0.3)
## points(x * s, x * c, bg=col, col=col, lwd=0, pch=21, cex=1.5*cex)
## points(x * s, x * c, bg=col, col="red", pch=20, cex=0.6*cex)
points(x * s, x * c, bg=col, col='black', pch=21, lwd=1/3, cex=0.7*cex)
## histogram
h <- hist(x, plot=FALSE)
hx <- -h$mids
hx <- c(hx[1], hx, hx[length(hx)])
hy <- h$density * max.x * 2
hy <- c(0, hy, 0)
polygon(hx, hy, col=rgb(0,0,1,alpha=0.5))
}
print.summary.hemo <- function(x, digits=max(6, getOption("digits")-1), ...)
{
cat("Filename: ", x$filename)
cat("\nBlood pressure:\n")
print(data.frame(x$bp))
}
summary.hemo <- function(object, ...)
{
if (!inherits(object, "hemo"))
stop("method is only for hemo objects")
res <- list(filename=object$filename, bp=object$bp)
class(res) <- "summary.hemo"
res
}
read.hemo <- function(file, monitor=FALSE, debug=FALSE)
{
if (is.character(file)) {
filename <- file
file <- file(file, "rb")
on.exit(close(file))
}
if (!inherits(file, "connection"))
stop("argument `file' must be a character string or connection")
if (!isOpen(file)) {
filename <- "(connection)"
open(file, "rb")
on.exit(close(file))
}
lines <- readLines(file)
if (debug) {
cat("The following was read from the file:\n")
print(lines)
}
bp1 <- NULL
bp2 <- NULL
pulse <- NULL
time <- NULL
is.r <- grep("^R", lines) # running
is.c <- grep("^C", lines) # comment
is.w <- grep("^W", lines) # weight
is.bp <- grep("^BP", lines) # blood pressure
if (length(is.r) > 0) {
duration <- details <- Ymd <- HM <- NULL
for (line in lines[is.r]) {
if (monitor)
cat("is.r:", line, "\n")
d <- strsplit(line, "[ ]+")[[1]]
Ymd <- c(Ymd, d[2])
HM <- c(HM, d[3])
duration <- c(duration, as.numeric(d[4]))
details <- c(details, paste(d[5:length(d)], collapse=" "))
}
t <- strptime(paste(Ymd, HM), format="%Y-%m-%d %H:%M")
if (any (is.na(t))) {
cat("bad time data:\n")
print(paste(Ymd, HM)[is.na(t)])
}
o <- order(t)
t <- t[o]
duration <- duration[o]
details <- details[o]
r <- data.frame(t, duration, details)
} else r <- NULL
if (length(is.c) > 0) {
comment <- Ymd <- HM <- NULL
for (line in lines[is.c]) {
if (monitor)
cat("is.c:", line, "\n")
d <- strsplit(line, "[ ]+")[[1]]
Ymd <- c(Ymd, d[2])
HM <- c(HM, d[3])
comment <- c(comment, paste(d[4:length(d)], collapse=" "))
}
t <- strptime(paste(Ymd, HM), format="%Y-%m-%d %H:%M")
if (any (is.na(t))) {
cat("bad time data:\n")
print(paste(Ymd, HM)[is.na(t)])
}
o <- order(t)
t <- t[o]
comment <- comment[o]
c <- data.frame(t, comment)
} else {
c <- NULL
}
if (length(is.w) > 0) {
Ymd <- HM <- weight <- NULL
for (line in lines[is.w]) {
if (monitor)
cat("is.w:", line, "\n")
d <- strsplit(line, "[ ]+")
Ymd <- c(Ymd, d[[1]][2])
HM <- c(HM, d[[1]][3])
weight <- c(weight, d[[1]][4])
}
t <- strptime(paste(Ymd, HM), format="%Y-%m-%d %H:%M")
timeOK <- !is.na(t)
if (sum(!timeOK)) {
cat("bad time data:\n")
print(paste(Ymd, HM)[!timeOK])
}
weight <- as.numeric(weight)
t <- t[timeOK]
weight <- weight[timeOK]
o <- order(t)
t <- t[o]
weight <- weight[o]
w <- data.frame(t, weight)
} else {
w <- NULL
}
if (length(is.bp) > 0) {
if (debug)
cat("The following are to be interpreted as blood-pressure lines:\n")
Ymd <- HM <- systolic <- diastolic <- pulse <- NULL
for (line in lines[is.bp]) {
if (monitor)
cat("is.bp:", line, "\n")
d <- strsplit(line, "[ ]+")
Ymd <- c(Ymd, d[[1]][2])
HM <- c(HM, d[[1]][3])
systolic <- c(systolic, d[[1]][4])
diastolic <- c(diastolic, d[[1]][5])
pulse <- c(pulse, d[[1]][6])
}
t <- strptime(paste(Ymd, HM), format="%Y-%m-%d %H:%M")
if (any (is.na(t))) {
cat("bad time data:\n")
print(paste(Ymd, HM)[is.na(t)])
}
systolic <- as.numeric(systolic)
diastolic <- as.numeric(diastolic)
pulse <- as.numeric(pulse)
o <- order(t)
t <- t[o]
systolic <- systolic[o]
diastolic <- diastolic[o]
bp <- data.frame(t, systolic, diastolic,
map=(2*diastolic + systolic)/3,
pp=systolic-diastolic,
pulse.rate=pulse)
} else {
bp <- NULL
}
rval <- list(filename=filename, bp=bp, w=w, c=c, r=r)
class(rval) <- "hemo"
rval
}
plot.hemo <- function(x, style=c("ts","clock","pairs"), which,
cex=par("cex"), debug=FALSE,
show.mean=TRUE,
show.lm=FALSE, show.spline=TRUE, ...)
{
style <- match.arg(style)
opar <- par(no.readonly=TRUE)
on.exit(par(opar))
if (style == "ts") {
par(mgp=c(2, 3/4, 0))
par(mar=c(2.5, 3, 1, 1.5))
if (missing(which))
which <- c(1, 2, 6)
lw <- length(which)
par(mfrow=c(lw, 1))
tlim <- range(c(x$bp$t, x$w$t), na.rm=TRUE)
for (w in which) {
if (1 == w)
ts.plot(x$bp$t, x$bp$systolic, ylab="Systolic [mm Hg]", cex=cex, tlim=tlim, show.lm=show.lm, green=c(90,119), orange=c(120,139.5), red=c(139.5,159))
if (2 == w)
ts.plot(x$bp$t, x$bp$diastolic, ylab="Diastolic [mm Hg]", cex=cex, tlim=tlim, show.lm=show.lm, green=c(60,79), orange=c(80,89.5), red=c(89.5,99))
if (3 == w)
ts.plot(x$bp$t, x$bp$map, ylab="MAP [mm Hg]", cex=cex, tlim=tlim, show.lm=show.lm)
if (4 == w)
ts.plot(x$bp$t, x$bp$pp, ylab="PP [mm Hg]", cex=cex, tlim=tlim, show.lm=show.lm)
if (5 == w)
ts.plot(x$bp$t, x$bp$pulse.rate, ylab="Pulse [beats/min]", cex=cex, tlim=tlim, show.lm=show.lm)
if (6 == w)
ts.plot(x$w$t, x$w$weight, ylab="Weight [lb]", cex=cex, tlim=tlim, show.lm=show.lm)
if (7 == w)
ts.plot(x$r$t, cumsum(x$r$duration), ylab="Running Time", cex=cex, tlim=tlim, show.lm=show.lm)
if (99 == w)
stop("cannot show statistics yet")
abline(v=x$c$t)
}
} else if (style == "clock") {
if (missing(which))
which <- c(1,2,5,99)
lw <- length(which)
if (lw == 2)
par(mfrow=c(2,2))
else if (lw > 2)
par(mfrow=c(2,2))
par(mgp=c(1.25,1.5/3,0))
par(mar=c(1.5,1.5,1.5,1.5))
for (w in which) {
if (1 == w)
clock.plot(x$bp$t, x$bp$systolic, " Systolic [mm Hg]",
R=c(90,120), R.col=c("lightgray","lightgray"),
cex=cex, show.mean=show.mean, green=c(90,119), orange=c(120,139.5), red=c(139.5,159))
if (2 == w)
clock.plot(x$bp$t, x$bp$diastolic, " Diastolic [mm Hg]",
R=c(60,80), R.col=c("lightgray","lightgray"),
cex=cex, show.mean=show.mean, green=c(60,79), orange=c(80,89.5), red=c(89.5,99))
if (3 == w)
clock.plot(x$bp$t, x$bp$map, " MAP [mm Hg]",
cex=cex, show.mean=show.mean)
if (4 == w)
clock.plot(x$bp$t, x$bp$pp, " PP [mm Hg]",
cex=cex, show.mean=show.mean)
if (5 == w)
clock.plot(x$bp$t, x$bp$pulse.rate, " Pulse [beats/min]",
cex=cex, show.mean=show.mean)
if (6 == w)
clock.plot(x$w$t, x$w$weight, " Weight [lb]",
cex=cex, show.mean=show.mean)
## Stats
if (7 == w)
stop("cannot display running data in clock form")
if (99 == w) {
par(mar=c(0,0,0,0))
plot(0:1, 0:1, axes=FALSE, type='n', xlab="", ylab="")
xx <- 0
dy <- 1/7
yy <- dy
text(xx, yy, paste(" Pulse:",
paste(format(fivenum(x$bp$pulse.rate), digits=1), collapse=" ")),
cex=cex, pos=4)
yy <- yy + dy
text(xx, yy, paste(" Pulse pressure:",
paste(format(fivenum(x$bp$pp), digits=1), collapse=" ")),
cex=cex, pos=4)
yy <- yy + dy
text(xx, yy, paste(" Arterial pressure:",
paste(format(fivenum(x$bp$map), digits=1), collapse=" ")),
cex=cex, pos=4)
yy <- yy + dy
text(xx, yy, paste(" Diastolic:",
paste(format(fivenum(x$bp$diastolic), digits=1), collapse=" ")),
cex=cex, pos=4)
yy <- yy + dy
text(xx, yy, paste(" Systolic:",
paste(format(fivenum(x$bp$systolic), digits=1), collapse=" ")),
cex=cex, pos=4)
yy <- yy + dy
text(xx, yy, "Min, Q1, Median, Q2, Max:", cex=1.2*cex, pos=4)
}
}
} else if (style == "pairs") {
if (missing(which))
which <- 2:3
pairs.plot(x, which=which)
} else
stop("cannot handle plot style ", style)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.