Prevent a function to block - r

In the package shapes there is a function called
estcov
that uses some method to give mean of tensors, but this is not the point of the question.
Everytime this function is called appears a plot, i want to stop it plotting without touching the code of the function,there is some trick to do this?
Here there is a riproducible code
S <- array(0,c(5,5,10) )
for (i in 1:10){
tem <- diag(5)+.1*matrix(rnorm(25),5,5)
S[,,i]<- tem
}
estcov( S , method="Procrustes")

The best way to do that is to send everything to a NULL dev, and close it afterward :
pdf(file = NULL)
estcov( S , method="Procrustes")
dev.off()

You could create a wrapper around estcov that redirects graphics to a temporary file, which is deleted afterwards.
estcov_no_plot <- function(...) {
temp_plot <- tempfile()
png(temp_plot)
on.exit({
dev.off(dev.cur())
file.remove(temp_plot)
})
shapes::estcov(...)
}
This example uses a new name for the function to remind you it's not the original. You could name it estcov, which would replace the package's function in your environment, but that might cause confusion.

What you can do is remove the part with the plot yourself (commented out below):
my_estcov <- function (S, method = "Riemannian", weights = 1, alpha = 1/2,
MDSk = 2)
{
out <- list(mean = 0, sd = 0, pco = 0, eig = 0, dist = 0)
M <- dim(S)[3]
if (length(weights) == 1) {
weights <- rep(1, times = M)
}
if (method == "Procrustes") {
dd <- estSS(S, weights)
}
if (method == "ProcrustesShape") {
dd <- estShape(S, weights)
}
if (method == "Riemannian") {
dd <- estLogRiem2(S, weights)
}
if (method == "Cholesky") {
dd <- estCholesky(S, weights)
}
if (method == "Power") {
dd <- estPowerEuclid(S, weights, alpha)
}
if (method == "Euclidean") {
dd <- estEuclid(S, weights)
}
if (method == "LogEuclidean") {
dd <- estLogEuclid(S, weights)
}
if (method == "RiemannianLe") {
dd <- estRiemLe(S, weights)
}
out$mean <- dd
sum <- 0
for (i in 1:M) {
sum <- sum + weights[i] * distcov(S[, , i], dd, method = method)^2/sum(weights)
}
out$sd <- sqrt(sum)
dist <- matrix(0, M, M)
for (i in 2:M) {
for (j in 1:(i - 1)) {
dist[i, j] <- distcov(S[, , i], S[, , j], method = method)
dist[j, i] <- dist[i, j]
}
}
out$dist <- dist
if (M > MDSk) {
ans <- cmdscale(dist, k = MDSk, eig = TRUE, add = TRUE,
x.ret = TRUE)
out$pco <- ans$points
out$eig <- ans$eig
#if (MDSk > 2) {
# shapes3d(out$pco[, 1:min(MDSk, 3)], axes3 = TRUE)
#}
#if (MDSk == 2) {
# plot(out$pco, type = "n", xlab = "MDS1", ylab = "MDS2")
# text(out$pco[, 1], out$pco[, 2], 1:length(out$pco[,
# 1]))
#}
}
out
}
You can even add a parameter (a logical plot = F) to control when plot or outputs.

Related

Error in Psych::Mediate: Object Not Found

I'm running a mediation analysis on a dataset in r and can't figure out how to get psych::mediate to work--I've done the same on another dataset before and didn't change anything, but it's not working with this new data for some reason.
I tried:
1. Turning 'condition' into a condition.f factor
2. Explicitly naming DATA a "data.frame"
3. Specifying different parameters such as "z" or "mod" in the function
4. Checked capitalization on all the variable column names.
None of the above seem to work.
library(psych)
DATA = STEX_S1_FINALCLEAN
Mediation_RA = psych::mediate( y = "DV_See", x = "Share_T", m = "Seff", data = DATA)
print(Mediation_RA,short=F)
I'd expect a full output with mediation values, but have gotten:
Error in psych::mediate(y = "DV_See", x = "Share_T", m = "Seff", data = DATA) :
object 'ex' not found
I don't see and object 'ex' anywhere, and that's not a name of any columns in the DATA data frame.
Following the suggestion of #r2evans, you can use the following modified function:
mymediate <- function (y, x, m = NULL, data, mod = NULL, z = NULL, n.obs = NULL,
use = "pairwise", n.iter = 5000, alpha = 0.05, std = FALSE,
plot = TRUE, zero = TRUE, main = "Mediation")
{
cl <- match.call()
if (class(y) == "formula") {
ps <- fparse(y)
y <- ps$y
x <- ps$x
m <- ps$m
mod <- ps$prod
ex <- ps$ex
x <- x[!ps$x %in% ps$m]
z <- ps$z
print(str(ps))
} else {
ex = NULL
}
all.ab <- NULL
if (is.numeric(y))
y <- colnames(data)[y]
if (is.numeric(x))
x <- colnames(data)[x]
if (!is.null(m))
if (is.numeric(m))
m <- colnames(data)[m]
if (!is.null(mod)) {
if (is.numeric(mod)) {
nmod <- length(mod)
mod <- colnames(data)[mod]
}
}
if (is.null(mod)) {
nmod <- 0
}
else {
nmod <- length(mod)
}
var.names <- list(IV = x, DV = y, med = m, mod = mod, z = z,
ex = ex)
if (any(!(unlist(var.names) %in% colnames(data)))) {
stop("Variable names not specified correctly")
}
if (ncol(data) == nrow(data)) {
raw <- FALSE
if (nmod > 0) {
stop("Moderation Analysis requires the raw data")
}
else {
data <- data[c(y, x, m, z), c(y, x, m, z)]
}
}
else {
data <- data[, c(y, x, m, z, ex)]
}
if (nmod == 1) {
mod <- c(x, mod)
nmod <- length(mod)
}
if (!is.matrix(data))
data <- as.matrix(data)
if ((dim(data)[1] != dim(data)[2])) {
n.obs = dim(data)[1]
if (!is.null(mod))
if (zero)
data <- scale(data, scale = FALSE)
C <- cov(data, use = use)
raw <- TRUE
if (std) {
C <- cov2cor(C)
}
}
else {
raw <- FALSE
C <- data
nvar <- ncol(C)
if (is.null(n.obs)) {
n.obs <- 1000
message("The data matrix was a correlation matrix and the number of subjects was not specified. \n n.obs arbitrarily set to 1000")
}
if (!is.null(m)) {
message("The replication data matrices were simulated based upon the specified number of subjects and the observed correlation matrix.")
eX <- eigen(C)
data <- matrix(rnorm(nvar * n.obs), n.obs)
data <- t(eX$vectors %*% diag(sqrt(pmax(eX$values,
0)), nvar) %*% t(data))
colnames(data) <- c(y, x, m)
}
}
if ((nmod > 0) | (!is.null(ex))) {
if (!raw) {
stop("Moderation analysis requires the raw data")
}
else {
if (zero) {
data <- scale(data, scale = FALSE)
}
}
}
if (nmod > 0) {
prods <- matrix(NA, ncol = length(ps$prod), nrow = nrow(data))
colnames(prods) <- paste0("V", 1:length(ps$prod))
for (i in 1:length(ps$prod)) {
prods[, i] <- apply(data[, ps$prod[[i]]], 1, prod)
colnames(prods)[i] <- paste0(ps$prod[[i]], collapse = "*")
}
data <- cbind(data, prods)
x <- c(x, colnames(prods))
}
if (!is.null(ex)) {
quads <- matrix(NA, ncol = length(ex), nrow = nrow(data))
colnames(quads) <- ex
for (i in 1:length(ex)) {
quads[, i] <- data[, ex[i]] * data[, ex[i]]
colnames(quads)[i] <- paste0(ex[i], "^2")
}
data <- cbind(data, quads)
x <- c(x, colnames(quads))
}
if (raw) {
C <- cov(data, use = use)
}
if (std) {
C <- cov2cor(C)
}
xy <- c(x, y)
numx <- length(x)
numy <- length(y)
if (!is.null(m)) {
numm <- length(m)
nxy <- numx + numy
m.matrix <- C[c(x, m), c(x, m), drop = FALSE]
}
else {
numm <- 0
nxy <- numx
}
df <- n.obs - nxy - 1
xy.matrix <- C[c(x, m), y, drop = FALSE]
total.reg <- matReg(x, y, m = m, z = z, C = C, n.obs = n.obs)
direct <- total.reg$beta
if (!is.null(z)) {
colnames(direct) <- paste0(colnames(direct), "*")
rownames(direct) <- paste0(rownames(direct), "*")
}
if (numm > 0) {
a.reg <- matReg(x = x, y = m, C = C, z = z, n.obs = n.obs)
b.reg <- matReg(c(x, m), y, C = C, z = z, n.obs = n.obs)
cprime.reg <- matReg(c(x, m), y, C = C, n.obs = n.obs,
z = z)
a <- a.reg$beta
b <- b.reg$beta[-(1:numx), , drop = FALSE]
c <- total.reg$beta
cprime <- cprime.reg$beta
all.ab <- matrix(NA, ncol = numm, nrow = numx)
for (i in 1:numx) {
all.ab[i, ] <- a[i, ] * t(b[, 1])
}
colnames(all.ab) <- m
rownames(all.ab) <- x
ab <- a %*% b
indirect <- c - ab
if (is.null(n.obs)) {
message("Bootstrap is not meaningful unless raw data are provided or the number of subjects is specified.")
mean.boot <- sd.boot <- ci.quant <- boot <- se <- tvalue <- prob <- NA
}
else {
boot <- psych:::boot.mediate(data, x, y, m, z, n.iter = n.iter,
std = std, use = use)
mean.boot <- colMeans(boot)
sd.boot <- apply(boot, 2, sd)
ci.quant <- apply(boot, 2, function(x) quantile(x,
c(alpha/2, 1 - alpha/2), na.rm = TRUE))
mean.boot <- matrix(mean.boot, nrow = numx)
sd.boot <- matrix(sd.boot, nrow = numx)
ci.ab <- matrix(ci.quant, nrow = 2 * numx * numy)
boots <- list(mean = mean.boot, sd = sd.boot, ci = ci.quant,
ci.ab = ci.ab)
}
}
else {
a.reg <- b.reg <- reg <- NA
a <- b <- c <- ab <- cprime <- boot <- boots <- indirect <- cprime.reg <- NA
}
if (!is.null(z)) {
var.names$IV <- paste0(var.names$IV, "*")
var.names$DV <- paste0(var.names$DV, "*")
var.names$med <- paste0(var.names$med, "*")
colnames(C) <- rownames(C) <- paste0(colnames(C), "*")
}
result <- list(var.names = var.names, a = a, b = b, ab = ab,
all.ab = all.ab, c = c, direct = direct, indirect = indirect,
cprime = cprime, total.reg = total.reg, a.reg = a.reg,
b.reg = b.reg, cprime.reg = cprime.reg, boot = boots,
boot.values = boot, sdnames = colnames(data), data = data,
C = C, Call = cl)
class(result) <- c("psych", "mediate")
if (plot) {
if (is.null(m)) {
moderate.diagram(result)
}
else {
mediate.diagram(result, main = main)
}
}
return(result)
}
You can test the mymediate function using the following example:
library(psych)
mod.k2 <- mymediate(y="OccupAsp", x=c("Intelligence","Siblings","FatherEd","FatherOcc"),
m= c(5:6), data=R.kerch, n.obs=767, n.iter=50)
print(mod.k2)

Subsetting in multiple Imputation ANOVA in R

I'd like to ask a question considering subsetting in R. I tried to calculate Multiple Imputation ANOVA using the function mi.anova (miceadds) in R. Actually there is no possibility to only use subsets of the input.
Afterwards I tried to restructure my mids structure into a datlist, subsetting it there and I wanted to return it to a mids structure which was not possible because of the unequal length of the data.frames.
As well I tried to use the with and pool function (mice) to handle the problem, which doesn't give me the expected output, I'd Need.
Actually my last solution would be to rewrite the mi.anova function from the miceadds package which allows me to use subsets. Honestly I don't feel very comfortable when trying to rewrite function, and I don't have any idea how to rewrite it.
Is there maybe anyone who could help me out? Or does anyone suggest another solution?
Thanks a lot & best regards,
Pascal
function (mi.res, formula, type = 2)
{
if (type == 3) {
TAM::require_namespace_msg("car")
}
mi.list <- mi.res
if (class(mi.list) == "mids.1chain") {
mi.list <- mi.list$midsobj
}
if (class(mi.list) == "mids") {
m <- mi.list$m
h1 <- list(rep("", m))
for (ii in 1:m) {
h1[[ii]] <- as.data.frame(mice::complete(mi.list,
ii))
}
mi.list <- h1
}
if (class(mi.res) == "mi.norm") {
mi.list <- mi.list$imp.data
}
if (type == 2) {
anova.imp0 <- lapply(mi.list, FUN = function(dat) {
stats::lm(formula, data = dat)
})
anova.imp <- lapply(anova.imp0, FUN = function(obj) {
summary(stats::aov(obj))
})
}
if (type == 3) {
Nimp <- length(mi.list)
vars <- all.vars(stats::as.formula(formula))[-1]
VV <- length(vars)
ma_contrasts <- as.list(1:VV)
names(ma_contrasts) <- vars
dat <- mi.list[[1]]
for (vv in 1:VV) {
ma_contrasts[[vars[vv]]] <- "contr.sum"
if (!is.factor(dat[, vars[vv]])) {
ma_contrasts[[vars[vv]]] <- NULL
}
}
anova.imp0 <- lapply(as.list(1:Nimp), FUN = function(ii) {
dat <- mi.list[[ii]]
mod1 <- stats::lm(formula, data = dat, contrasts = ma_contrasts)
return(mod1)
})
anova.imp <- lapply(as.list(1:Nimp), FUN = function(ii) {
obj <- anova.imp0[[ii]]
car::Anova(obj, type = 3)
})
}
if (type == 2) {
FF <- nrow(anova.imp[[1]][[1]]) - 1
}
if (type == 3) {
FF <- nrow(anova.imp[[1]]["F value"]) - 2
}
anova.imp.inf <- t(sapply(1:FF, FUN = function(ff) {
micombine.F(sapply(1:(length(anova.imp)), FUN = function(ii) {
if (type == 2) {
r1 <- anova.imp[[ii]][[1]]$"F value"[ff]
}
if (type == 3) {
r1 <- anova.imp[[ii]]$"F value"[ff + 1]
}
return(r1)
}), df1 = ifelse(type == 2, anova.imp[[1]][[1]]$Df[ff],
anova.imp[[1]]["Df"][ff + 1, 1]), display = FALSE)
}))
res <- anova.imp.inf[, c(3, 4, 1, 2)]
res <- matrix(res, ncol = 4)
res[, 3] <- round(res[, 3], 4)
res[, 4] <- round(res[, 4], 6)
g1 <- rownames(anova.imp[[1]][[1]])[1:FF]
if (type == 3) {
g1 <- rownames(anova.imp[[1]])[1 + 1:FF]
}
rownames(res) <- g1
res <- data.frame(res)
if (type == 2) {
SS <- rowMeans(matrix(unlist(lapply(anova.imp, FUN = function(ll) {
ll[[1]][, 2]
})), ncol = length(mi.list)))
}
if (type == 3) {
SS <- rowMeans(matrix(unlist(lapply(anova.imp, FUN = function(ll) {
l2 <- ll["Sum Sq"][-1, 1]
return(l2)
})), ncol = length(mi.list)))
}
r.squared <- sum(SS[-(FF + 1)])/sum(SS)
res$eta2 <- round(SS[-(FF + 1)]/sum(SS), 6)
res$partial.eta2 <- round(SS[-(FF + 1)]/(SS[-(FF + 1)] +
SS[FF + 1]), 6)
g1 <- c("F value", "Pr(>F)")
colnames(res)[3:4] <- g1
colnames(res)[1:2] <- c("df1", "df2")
c1 <- colnames(res)
res <- rbind(res, res[1, ])
rownames(res)[nrow(res)] <- "Residual"
res[nrow(res), ] <- NA
res <- data.frame(SSQ = SS, res)
colnames(res)[-1] <- c1
cat("Univariate ANOVA for Multiply Imputed Data", paste0("(Type ",
type, ")"), " \n\n")
cat("lm Formula: ", formula)
cat(paste("\nR^2=", round(r.squared, 4), sep = ""), "\n")
cat("..........................................................................\n")
cat("ANOVA Table \n")
print(round(res, 5))
invisible(list(r.squared = r.squared, anova.table = res,
type = type))
}

Modify SPDEP package - insert new function

I am trying to modify the stsls function of the R package spdep.
The function compute a spatial autoregressive function using a two stage least square. For both stages, the function uses the same spatial matrix.
What I want is to create a new function, say stslsm, which uses two different spatial matrices, one for the first stage (inlistw), one for the second stage (listw).
For this reason, I took the stsls function, I added a new entry, inlistw, and modified accordingly the script. For those who are interested, the code is at the bottom of this post, but please consider that this is just a first trial.
Now the problem is that I don't know how to insert this new function in the spdep package.
I read different posts on this issue. The most recurrent suggestion is:
unlockBinding("spdep", loadNamespace("spdep"));
assignInNamespace("stslsm", stslsm, ns=asNamespace("spdep"), envir=loadNamespace("spdep"));
assign("stslsm", stslsm, envir=env);
lockBinding(stslsm, loadNamespace("spdep"));
But after the second line of code I get the following
Error in bindingIsLocked(x, ns) : no binding for "stslsm"
I got stuck here. Do you have any suggestion?
function (formula, data = list(), listw, inlistw,zero.policy = NULL,
na.action = na.fail, robust = FALSE, HC = NULL, legacy = FALSE,
W2X = TRUE) {
if (!inherits(listw, "listw"))
stop("No neighbourhood list")
if (is.null(zero.policy))
zero.policy <- get("zeroPolicy", envir = .spdepOptions)
stopifnot(is.logical(zero.policy))
if (class(formula) != "formula")
formula <- as.formula(formula)
mt <- terms(formula, data = data)
mf <- lm(formula, data, na.action = na.action, method = "model.frame")
na.act <- attr(mf, "na.action")
if (!is.null(na.act)) {
subset <- !(1:length(listw$neighbours) %in% na.act)
listw <- subset(listw, subset, zero.policy = zero.policy)
}
y <- model.extract(mf, "response")
if (any(is.na(y)))
stop("NAs in dependent variable")
X <- model.matrix(mt, mf)
if (any(is.na(X)))
stop("NAs in independent variable")
if (robust) {
if (is.null(HC))
HC <- "HC0"
if (!any(HC %in% c("HC0", "HC1")))
stop("HC must be one of HC0, HC1")
}
Wy <- lag.listw(listw, y, zero.policy = zero.policy)
dim(Wy) <- c(nrow(X), 1)
colnames(Wy) <- c("Rho")
n <- NROW(X)
m <- NCOL(X)
xcolnames <- colnames(X)
K <- ifelse(xcolnames[1] == "(Intercept)", 2, 1)
if (m > 1) {
WX <- matrix(nrow = n, ncol = (m - (K - 1)))
if (W2X)
WWX <- matrix(nrow = n, ncol = ncol(WX))
for (k in K:m) {
wx <- lag.listw(inlistw, X[, k], zero.policy = zero.policy)
if (W2X)
wwx <- lag.listw(inlistw, wx, zero.policy = zero.policy)
if (any(is.na(wx)))
stop("NAs in lagged independent variable")
WX[, (k - (K - 1))] <- wx
if (W2X)
WWX[, (k - (K - 1))] <- wwx
}
if (W2X)
inst <- cbind(WX, WWX)
else inst <- WX
}
if (K == 2 && listw$style != "W") {
wx1 <- as.double(rep(1, n))
wx <- lag.listw(inlistw, wx1, zero.policy = zero.policy)
if (W2X)
wwx <- lag.listw(inlistw, wx, zero.policy = zero.policy)
if (m > 1) {
inst <- cbind(wx, inst)
if (W2X)
inst <- cbind(wwx, inst)
}
else {
inst <- matrix(wx, nrow = n, ncol = 1)
if (W2X)
inst <- cbind(inst, wwx)
}
}
result <- tsls(y = y, yend = Wy, X = X, Zinst = inst, robust = robust,
HC = HC, legacy = legacy)
result$zero.policy <- zero.policy
result$robust <- robust
if (robust)
result$HC <- HC
result$legacy <- legacy
result$listw_style <- listw$style
result$call <- match.call()
class(result) <- "stsls"
result
}

prediction.strength in Package fpc

I am using the function prediction.strength in the r Package fpc with k-medoids algorithms.
here is my code
prediction.strength(data,2,6,M=10,clustermethod=pamkCBI,DIST,krange=2:6,diss=TRUE,usepam=TRUE)
somehow I get the error message
Error in switch(method, kmeans = kmeans(xdata[indvec[[l]][[i]], ], k, :
EXPR must be a length 1 vector
Does anybody have experience with this r command? There are simple examples like
iriss <- iris[sample(150,20),-5]
prediction.strength(iriss,2,3,M=3,method="pam")
but my problem is that I am using dissimilarity matrix instead of the data itself for the k-medoids algorithms. I don't know how should I correct my code in this case.
Please note that in the package help the following is stated for the prediction.strength:
xdats - data (something that can be coerced into a matrix). Note that this can currently
not be a dissimilarity matrix.
I'm afraid you'll have to hack the function to get it to handle a distance matrix. I'm using the following:
pred <- function (distance, Gmin = 2, Gmax = 10, M = 50,
classification = "centroid", cutoff = 0.8, nnk = 1, ...)
{
require(cluster)
require(class)
xdata <- as.matrix(distance)
n <- nrow(xdata)
nf <- c(floor(n/2), n - floor(n/2))
indvec <- clcenters <- clusterings <- jclusterings <- classifications <- list()
prederr <- list()
dist <- as.matrix(distance)
for (k in Gmin:Gmax) {
prederr[[k]] <- numeric(0)
for (l in 1:M) {
nperm <- sample(n, n)
indvec[[l]] <- list()
indvec[[l]][[1]] <- nperm[1:nf[1]]
indvec[[l]][[2]] <- nperm[(nf[1] + 1):n]
for (i in 1:2) {
clusterings[[i]] <- as.vector(pam(as.dist(dist[indvec[[l]][[i]],indvec[[l]][[i]]]), k, diss=TRUE))
jclusterings[[i]] <- rep(-1, n)
jclusterings[[i]][indvec[[l]][[i]]] <- clusterings[[i]]$clustering
centroids <- clusterings[[i]]$medoids
j <- 3 - i
classifications[[j]] <- classifdist(as.dist(dist), jclusterings[[i]],
method = classification, centroids = centroids,
nnk = nnk)[indvec[[l]][[j]]]
}
ps <- matrix(0, nrow = 2, ncol = k)
for (i in 1:2) {
for (kk in 1:k) {
nik <- sum(clusterings[[i]]$clustering == kk)
if (nik > 1) {
for (j1 in (1:(nf[i] - 1))[clusterings[[i]]$clustering[1:(nf[i] -
1)] == kk]) {
for (j2 in (j1 + 1):nf[i]) if (clusterings[[i]]$clustering[j2] ==
kk)
ps[i, kk] <- ps[i, kk] + (classifications[[i]][j1] ==
classifications[[i]][j2])
}
ps[i, kk] <- 2 * ps[i, kk]/(nik * (nik -
1))
}
}
}
prederr[[k]][l] <- mean(c(min(ps[1, ]), min(ps[2,
])))
}
}
mean.pred <- numeric(0)
if (Gmin > 1)
mean.pred <- c(1)
if (Gmin > 2)
mean.pred <- c(mean.pred, rep(NA, Gmin - 2))
for (k in Gmin:Gmax) mean.pred <- c(mean.pred, mean(prederr[[k]]))
optimalk <- max(which(mean.pred > cutoff))
out <- list(predcorr = prederr, mean.pred = mean.pred, optimalk = optimalk,
cutoff = cutoff, method = clusterings[[1]]$clustermethod,
Gmax = Gmax, M = M)
class(out) <- "predstr"
out
}

Saving huge model object to file

Say you have a model object of class 'varrest' returned from a VAR() regression operation.
I want to save the model to a file, but not all data which was used to estimate the coefficients.
How can one just save the model specification wihtout the training data?
Because when I save the model it has a file size of over 1GB and therefore loading does take its time.
Can one save objects without some attributes?
The predict.varest function starts out with this code:
K <- object$K
p <- object$p
obs <- object$obs
type <- object$type
data.all <- object$datamat
ynames <- colnames(object$y)
You can then investigate how much pruning you might achieve:
data(Canada)
tcan <-
VAR(Canada, p = 2, type = "trend")
names(tcan)
# [1] "varresult" "datamat" "y" "type" "p"
# [6] "K" "obs" "totobs" "restrictions" "call"
object.size(tcan[c("K","p", "obs", "type", "datamat", "y")] )
#15080 bytes
object.size(tcan)
#252032 bytes
So the difference is substantial, but just saving those items is not sufficient because the next line in predict.varest is:
B <- Bcoef(object)
You will need to add that object to the list above and then construct a new predict-function that accepts something less than the large 'varresult' node of the model object. Also turned out that there was a downstream call to an internal function that needs to be stored. (You will need to decide in advance what interval you need for prediction.)
tsmall <- c( tcan[c("K","p", "obs", "type", "datamat", "y", "call")] )
tsmall[["Bco"]] <- Bcoef(tcan)
tsmall$sig.y <- vars:::.fecov(x = tcan, n.ahead = 10)
And the modified predict function will be:
sm.predict <- function (object, ..., n.ahead = 10, ci = 0.95, dumvar = NULL)
{
K <- object$K
p <- object$p
obs <- object$obs
type <- object$type
data.all <- object$datamat
ynames <- colnames(object$y)
n.ahead <- as.integer(n.ahead)
Z <- object$datamat[, -c(1:K)]
# This used to be a call to Bcoef(object)
B <- object$Bco
if (type == "const") {
Zdet <- matrix(rep(1, n.ahead), nrow = n.ahead, ncol = 1)
colnames(Zdet) <- "const"
}
else if (type == "trend") {
trdstart <- nrow(Z) + 1 + p
Zdet <- matrix(seq(trdstart, length = n.ahead), nrow = n.ahead,
ncol = 1)
colnames(Zdet) <- "trend"
}
else if (type == "both") {
trdstart <- nrow(Z) + 1 + p
Zdet <- matrix(c(rep(1, n.ahead), seq(trdstart, length = n.ahead)),
nrow = n.ahead, ncol = 2)
colnames(Zdet) <- c("const", "trend")
}
else if (type == "none") {
Zdet <- NULL
}
if (!is.null(eval(object$call$season))) {
season <- eval(object$call$season)
seas.names <- paste("sd", 1:(season - 1), sep = "")
cycle <- tail(data.all[, seas.names], season)
seasonal <- as.matrix(cycle, nrow = season, ncol = season -
1)
if (nrow(seasonal) >= n.ahead) {
seasonal <- as.matrix(cycle[1:n.ahead, ], nrow = n.ahead,
ncol = season - 1)
}
else {
while (nrow(seasonal) < n.ahead) {
seasonal <- rbind(seasonal, cycle)
}
seasonal <- seasonal[1:n.ahead, ]
}
rownames(seasonal) <- seq(nrow(data.all) + 1, length = n.ahead)
if (!is.null(Zdet)) {
Zdet <- as.matrix(cbind(Zdet, seasonal))
}
else {
Zdet <- as.matrix(seasonal)
}
}
if (!is.null(eval(object$call$exogen))) {
if (is.null(dumvar)) {
stop("\nNo matrix for dumvar supplied, but object varest contains exogenous variables.\n")
}
if (!all(colnames(dumvar) %in% colnames(data.all))) {
stop("\nColumn names of dumvar do not coincide with exogen.\n")
}
if (!identical(nrow(dumvar), n.ahead)) {
stop("\nRow number of dumvar is unequal to n.ahead.\n")
}
if (!is.null(Zdet)) {
Zdet <- as.matrix(cbind(Zdet, dumvar))
}
else {
Zdet <- as.matrix(dumvar)
}
}
Zy <- as.matrix(object$datamat[, 1:(K * (p + 1))])
yse <- matrix(NA, nrow = n.ahead, ncol = K)
# This used to be a call to vars:::.fecov
sig.y <- object$sig.y
for (i in 1:n.ahead) {
yse[i, ] <- sqrt(diag(sig.y[, , i]))
}
yse <- -1 * qnorm((1 - ci)/2) * yse
colnames(yse) <- paste(ci, "of", ynames)
forecast <- matrix(NA, ncol = K, nrow = n.ahead)
lasty <- c(Zy[nrow(Zy), ])
for (i in 1:n.ahead) {
lasty <- lasty[1:(K * p)]; print(lasty); print(B)
Z <- c(lasty, Zdet[i, ]) ;print(Z)
forecast[i, ] <- B %*% Z
temp <- forecast[i, ]
lasty <- c(temp, lasty)
}
colnames(forecast) <- paste(ynames, ".fcst", sep = "")
lower <- forecast - yse
colnames(lower) <- paste(ynames, ".lower", sep = "")
upper <- forecast + yse
colnames(upper) <- paste(ynames, ".upper", sep = "")
forecasts <- list()
for (i in 1:K) {
forecasts[[i]] <- cbind(forecast[, i], lower[, i], upper[,
i], yse[, i])
colnames(forecasts[[i]]) <- c("fcst", "lower", "upper",
"CI")
}
names(forecasts) <- ynames
result <- list(fcst = forecasts, endog = object$y, model = object,
exo.fcst = dumvar)
class(result) <- "varprd"
return(result)
}
Either
set the attributes you do not want to NULL, or
copy the parts you want to a new object, or
call the save() function with proper indexing.

Resources