# Copies as list into an environment
assign.list = function(li, envir=sys.frame(-1),clone.env=TRUE) {
if (is.null(li)) {return()}
if (!clone.env) {
for (i in 1:length(li)) {
assign(names(li)[i],li[[i]],envir=envir)
}
} else {
for (i in 1:length(li)) {
obj = li[[i]]
if (is.environment(obj)) {
obj = clone.environment(obj)
}
assign(names(li)[i],obj,envir=envir)
}
}
}
matrix.get.rows = function(mat,col.val,col.names=names(col.val)) {
restore.point("matrix.get.rows")
if (!is.matrix(mat))
mat = as.matrix(mat)
if (!is.list(col.val))
col.val = as.list(col.val)
mwhich(mat,cols=col.names,vals=col.val,'eq','AND')
}
plot.multi.lines = function(mat=NULL,xvar,yvar,ynames=yvar,col=NULL,ylim=NULL,xlab=xvar,ylab="",
legend.pos=NULL,legend.title=NULL,add=FALSE,lwd=1,...) {
if (is.null(ylim)) {
ylim = range(mat[,yvar])
if (!is.null(legend.pos)) {
#if (legend.pos=="topleft" | legend.pos == "topright") {
#ylim[2] = ylim[2]+0.2*diff(ylim)
#}
}
}
ny = NROW(yvar)
if (is.null(col)) {
if (ny<=5) {
col=c("blue","red","green","black","orange")[1:ny]
} else {
col = rainbow(ny)
}
}
if (!add) {
plot(mat[,xvar],mat[,yvar[1]],type="n",ylim=ylim,xlab=xlab,ylab=ylab,...)
}
# Draw lines
for (i in 1:NROW(yvar))
lines(mat[,xvar],mat[,yvar[i]], col=col[i],lwd=lwd)
# Draw lines once more dotted, so that we can better see lines that are on top of each other better
if (NROW(yvar)>1) {
# Draw lines
for (i in (NROW(yvar)-1):1)
lines(mat[,xvar],mat[,yvar[i]], col=col[i],lty=2,lwd=lwd)
}
# Draw legend, if desired
if (!is.null(legend.pos)) {
legend(legend.pos, legend=ynames, fill=col,title=legend.title)
}
}
# Get a matrix with all rows that are unique in cols[1] and add a count
get.unique.table = function(dat,cols, add.count = TRUE) {
un = unique(dat[,cols[1]])
rows = match(un,dat[,cols[1]])
mat = cbind(dat[rows,cols],as.numeric(table(dat[,cols[1]])))
colnames(mat) = c(colnames(dat[1:2,cols]),"count")
mat
}
# Generate a matrix of polynomials of order o
cross.poly.mat = function(mat,cols=colnames(mat),ord=2) {
nc = NROW(cols)
li = replicate(nc,list(0:ord))
grid = expand.grid(li)
fun.pol = function(pol) {
ret = 1
for (k in 1:NROW(pol))
ret = ret * mat[,k]^pol[k]
ret
}
poly = apply(grid,1,fun.pol)
name.fun = function(pol,names=1:NROW(pol)) {
use = pol>0
paste(names[use],"^",pol[use],sep="",collapse="")
}
colnames(poly)=apply(grid,1,name.fun,names=cols)
poly = poly[,-1]
poly
}
# Call for debugging
#checkUsageEnv(globalenv())
# Looks through all loaded functions and searches for
# global variables that are used within the functions
# this is a common source for errors
check.global.vars = function() {
require(codetools)
print("Usage of global variables in loaded functions:")
funs = ls.funs(env=globalenv())
for (fn in funs) {
cmd = paste("findGlobals(",fn,",merge=FALSE)$variables",sep="")
glob = try(eval(parse(text=cmd)))
if (length(glob)>0) {
print("")
print(paste(paste(fn,": "),paste(glob,collapse=", ")))
}
}
}
#check.global.vars()
with.floor = function(mat,floor=0) {
mat[mat<floor] = floor
mat
}
with.floor.and.ceiling = function(mat,floor,ceiling) {
mat[mat<floor] = floor
mat[mat>ceiling] = ceiling
mat
}
with.ceiling = function(mat,ceiling) {
mat[mat>ceiling] = ceiling
mat
}
sublist = function(li, cols, simplify = TRUE) {
sl = list()
if (!simplify | length(cols) > 1) {
for (i in 1:length(li)) {
sl[[i]] = li[[i]][cols]
}
} else {
for (i in 1:length(li)) {
sl[[i]] = li[[i]][[cols]]
}
}
return(sl)
}
# a = list(x=1:10,y=c("Hi","you!"),z=0)
# b = a
# li = list(a,b)
# sublist(li,cols=c("x","z"))
# sublist(li,"y")
rbind.list = function(li, cols=NULL, only.common.cols=FALSE) {
if (length(li)==1) {
return(li[[1]])
}
if (only.common.cols) {
names = colnames(li[[1]])
for (i in 2:length(li)) {
names = intersect(names,colnames(li[[i]]))
}
if (length(names)<1) {
warning("Matrices in list have no common columns")
return(NULL)
}
len = sapply(li,NROW,simplify=TRUE)
mat = matrix(NA,sum(len),length(names))
colnames(mat) = names
rowstart = 1
for (i in 1:length(li)) {
rowend = rowstart+len[i]-1
mat[rowstart:rowend,] = li[[i]][,names]
rowstart = rowend+1
}
return(mat)
}
if (is.null(cols)) {
return(do.call("rbind",li))
} else {
return(do.call("rbind",li)[,cols])
}
}
cbind.list = function(li) {
return(do.call("cbind",li))
}
x = list(1:10,11:20)
rbind.list(x)
sk.findInterval = function(x, vec, match.smaller=TRUE, vec.ordered = "increasing",...) {
#restore.local.objects("sk.findInterval")
if (vec.ordered == "increasing") {
ind = findInterval(x,vec,...)
if (!match.smaller)
ind = ind +1
return(ind)
} else {
vec.ord = order(vec)
#ind.ord = findInterval(x,vec[vec.ord],...)
ind.ord = findInterval(x,vec[vec.ord])
if (!match.smaller) {
same = x %in% vec
ind.ord[!same] = ind.ord[!same] +1
}
return(vec.ord[ind.ord])
}
}
#sk.findInterval(1:10,vec = c(0,5,1,12,9), match.smaller = FALSE, vec.ordered = FALSE)
paste.matrix.cols = function(mat,cols=1:NCOL(mat),...) {
if (NROW(cols)==2) {
return(paste(mat[,cols[1]],mat[,cols[2]],...))
} else if (NROW(cols)==3) {
return(paste(mat[,cols[1]],mat[,cols[2]],mat[,cols[3]],...))
} else {
code = paste("mat[,",cols,"]",collapse=",")
code = paste("paste(",code,",...)",sep="")
return(eval(parse(text=code)))
}
}
paste.matrix.rows = function(mat,rows=1:NROW(mat),...) {
if (NROW(rows)==2) {
return(paste(mat[rows[1],],mat[rows[2],],...))
} else if (NROW(rows)==3) {
return(paste(mat[rows[1],],mat[rows[2],],mat[rows[3],],...))
} else {
code = paste("mat[",rows,",]",collapse=",")
code = paste("paste(",code,",...)",sep="")
return(eval(parse(text=code)))
}
}
# mat = matrix(1:100,10,10)
# paste.matrix.cols(mat)
# paste.matrix.rows(mat,sep=",")
add.rowvec = function(m,v) {
return(t(t(m) +v))
}
#' APPROXEQ Are a and b approximately equal (to within a specified tolerance)?
#' p = approxeq(a, b, thresh)
#' 'tol' defaults to 1e-3.
approxeq = function(a, b, tol=1e-3) {
isTRUE(all.equal(a,b,tol=tol, check.attributes=FALSE))
}
all.eq = function(...) {
isTRUE(all.equal(...,check.attributes=FALSE))
}
# Code seems more complicated than neccessary, but I tried to avoid
# parent.env(cenv)<- ...
# as they may become deprecated
clone.environment = function(env, made.clones=ListEnv(org = list(), copy = list()), clone.parents=TRUE, clone.global = FALSE, exclude = NULL, clone.children = TRUE) {
penv = parent.env(env)
#Clone parents
if (clone.parents & (!(identical(penv,emptyenv())
| (identical(penv,globalenv()) & ! clone.global)))) {
cpenv = clone.environment(penv, made.clones = made.clones, clone.parents = TRUE)
} else {
cpenv <- penv
}
if (length(made.clones$org) > 0) {
for (i in 1:length(made.clones$org)) {
if (identical(made.clones$org[[i]],env)) {
return(made.clones$copy[[i]])
}
}
}
cenv = new.env(parent=cpenv)
ind = length(made.clones$org)+1
made.clones$org[[ind]] = env
made.clones$copy[[ind]] = cenv
#Clone children
names = setdiff(ls(env),exclude)
#browser()
if (clone.children) {
for (na in names) {
# If an error occurs here, the variable [[
obj = env[[na]]
if (is.environment(obj)) {
obj = clone.environment(obj, made.clones = made.clones, clone.parents = TRUE, clone.global = clone.global)
cenv[[na]] <- obj
} else {
cenv[[na]] <- obj
}
}
} else {
for (na in names) {
cenv[[na]] <- env[[na]]
}
}
class(cenv) <- class(env)
return(cenv)
}
clone.env = function(...) clone.environment(...)
#
# env1 = ListEnv(a=10, b="Hi")
# env2 = new.ListEnv(parent=env1)
# env2$c = "c"
# env1$env = env2
# env2$a
# cenv = clone.environment(env2)
ls.funs <-function(env=sys.frame(-1)) {
unlist(lapply(ls(env=env),function(x)if (is.function(get(x)))x))
}
ls.vars <- function(env=sys.frame(-1)) {
unlist(lapply(ls(env=env),function(x)if(!is.function(get(x)))x))
}
currentenv = function() {
sys.parent(1)
}
copy.env = function(dest=sys.frame(sys.parent(1)),source=sys.frame(sys.parent(1)),
names = NULL, name.change = NULL, exclude=NULL) {
#store.local.objects() # DO NOT !!!!
#restore.local.objects("copy.env")
if (is.null(name.change)) {
if (is.environment(source)) {
if (is.null(names))
names = ls(envir=source)
names = setdiff(names,exclude)
for (na in names) {
assign(na,get(na,envir=source), envir=dest)
}
}
if (is.list(source)) {
if (is.null(names))
names = names(source)
names = setdiff(names,exclude)
for (na in names) {
assign(na,source[[na]], envir=dest)
}
}
} else {
if (is.environment(source)) {
if (is.null(names))
names = ls(envir=source)
names = setdiff(names,exclude)
for (na in names) {
ind = match(na,name.change[,1])
if (!is.na(ind)) {
assign(name.change[ind,2],get(na,envir=source), envir=dest)
} else {
assign(na,get(na,envir=source), envir=dest)
}
}
}
if (is.list(source)) {
if (is.null(names))
names = names(source)
names = setdiff(names,exclude)
for (na in names) {
ind = match(na,name.change[,1])
if (!is.na(ind)) {
assign(name.change[ind,2],source[[na]], envir=dest)
} else {
assign(na,source[[na]], envir=dest)
}
}
}
}
}
copy.into.env = function(dest=sys.frame(sys.parent(1)), source=sys.frame(sys.parent(1)), names = NULL, name.change = NULL,exclude=NULL) {
copy.env(dest,source,names,name.change,exclude)
}
copy.into.list = function(dest=NULL, source=sys.frame(sys.parent(1)), names = NULL,exclude=NULL,overwrite=TRUE) {
if (is.null(dest)) {
if (is.list(source)) {
return(source)
} else {
dest=list()
}
}
stopifnot(is.list(dest))
if (!overwrite) {
excluder = c(exclude,names(dest))
}
if (is.environment(source)) {
if (is.null(names))
names = ls(envir=source)
names = setdiff(names,exclude)
for (na in names) {
dest[[na]]=get(na,envir=source)
}
}
if (is.list(source)) {
if (is.null(names))
names = names(source)
names = setdiff(names,exclude)
for (na in names) {
dest[[na]]=source[[na]]
}
}
return(dest)
}
set.default = function(env,name,x, overwrite.null = TRUE, inherits = TRUE) {
if (is.environment(env)) {
if (!exists(name,envir=env, inherits = inherits)) {
env[[name]] <- x
} else {
if (overwrite.null & is.null(env[[name]])) {
env[[name]] <- x
}
}
return(env)
} else if (is.list(env)) {
if (overwrite.null) {
if (is.null(env[[name]])) {
env[[name]] <- x
}
} else if (!(name %in% names(env))) {
env[[name]] <- x
}
return(env)
}
}
# Calculates the 2dimensional paretofrontier of the points val1 and val2
# The function returns the indices of the points that lie on the Pareto Frontier
# ordered by val1 and val2.
sk.pareto.frontier = function(val1,val2, tol=0, ord = NULL) {
if (is.null(ord))
ord = order(val1,val2,decreasing=TRUE)
val2 = val2[ord]
cummax2 = c(-Inf,cummax(val2[-NROW(val2)]))
val2.inc = val2 > cummax2 + tol
ord = ord[val2.inc]
return(ord)
}
# Finds position where the function f becomes zero
# First tries find.root and if this fails tries optimize
findzero = function(f, lower, upper, tol = .Machine$double.eps*10,result.tol = tol, try.uniroot=TRUE,...) {
if (try.uniroot) {
ret = tryCatch(uniroot(f,lower=lower,upper=upper,...), error = function(e) NULL)
if (!is.null(ret)) {
return(ret$root)
}
}
f.sqr = function(...) f(...)^2
ret = tryCatch(optimize(f.sqr,lower=lower,upper=upper,tol=tol,...), error = function(e) NULL)
if (is.null(ret)) {
warning("findzero: error in optimize")
return(NA)
} else if (abs(ret$objective)>result.tol) {
warning("findzero: no solution found with optimize (min = ",ret$objective," > result.tol=",result.tol,")")
return(NA)
}
ret$min
}
# A wrapper for optimization. Allows to specify which variables shall be free
# Has the same syntax for one and multidimensional optmization
# Uses optim, omptimize or a grid search
sk.optim = function(par,f, lower = NULL, upper = NULL, free.par = 1:NROW(par), method="default",
num.grid.steps = NULL,maximize=TRUE,f.can.take.matrix = FALSE,tol=.Machine$double.eps^0.25,...) {
#restore.point(""sk.optim")
n.par = NROW(par)
if (!is.numeric(free.par))
free.par = which(free.par)
n.free = NROW(free.par)
if (n.free == 0) {
warning("No free parameters!")
return(list(par=par,value=f(par,...)))
}
if (n.free != n.par) {
sgn = 1
if (maximize & n.free > 1 & method != "grid")
sgn = -1
g = function(x,...) {
if (is.matrix(x)) {
mat = matrix(par,NROW(x),NROW(par),byrow=TRUE)
mat[,free.par] = x
return(sgn*f(mat,...))
} else {
p = par
p[free.par]=x
return(sgn*f(p,...))
}
}
} else {
g = f
}
if (method=="default") {
if (free.par == 1 & !is.null(lower)) {
method = "optimize"
} else if (!is.null(lower)) {
method = "L-BFGS-B"
} else {
method = "Nelder-Mead"
}
}
if (method == "grid") {
if (is.null(num.grid.steps))
stop("You have to specify num.grid.steps if you are using the grid method")
num.grid.steps = rep(num.grid.steps,length.out=n.par)
steps.li = lapply(free.par, function(i) seq(lower[i],upper[i],length=num.grid.steps[i]))
par.mat = make.grid.matrix(x=steps.li)
if (f.can.take.matrix) {
val = g(par.mat,...)
} else {
val = sapply(1:NROW(par.mat), function(ind) g(par.mat[ind,],...))
}
if (maximize) {
opt.ind = which.max(val)
} else {
opt.ind = which.min(val)
}
par.opt = par
par.opt[free.par]= par.mat[opt.ind,]
return(list(par=par.opt, value = val[opt.ind]))
}
# Use optimize
if (n.free == 1) {
ret = optimize(g,lower = lower[free.par], upper = upper[free.par],
maximum = maximize,tol=tol,...)
par.opt = par
if (maximize) {
par.opt[free.par] = ret$maximum
} else {
par.opt[free.par] = ret$minimum
}
return(list(opt.ret = ret, par=par.opt, value = ret$objective))
}
if (method == "L-BFGS-B") {
ret = optim(par[free.par],g,method=method,tol=tol,...)
} else {
if (is.null(lower)) {
ret = optim(par[free.par],g,method=method,tol=tol)
} else {
stop("Only methods grid and L-BFGS-B so far implemented for constrained, multivariable optimization")
}
}
par.opt = par
par.opt[free.par] = ret$par
return(list(opt.ret = ret, par=par.opt, value = ret$value))
}
# A function similar to expand.grid, but different ordering of columns
make.grid.matrix = function(x=lapply(x.dim,function(n) 1:n),x.dim=NULL,n=NULL) {
restore.point("make.grid.matrix")
#restore.point(""make.grid.matrix")
if (!is.list(x)) {
# Simply a matrix
if (is.null(n) & is.null(x.dim)) {
return(x)
}
mat = matrix(NA,nrow=NROW(x)^n,ncol=n)
for (i in 1:n) {
mat[,i] = rep( rep(x,each=NROW(x)^(n-i)), times = NROW(x)^(i-1))
}
return (mat)
} else {
n = length(x)
if (is.null(x.dim)) {
x.dim = sapply(x,length)
}
mat = matrix(NA,nrow=prod(x.dim),ncol=n)
x.dim = c(1,x.dim,1,1)
for (i in 1:n) {
mat[,i] = rep( rep(x[[i]],each=prod(x.dim[(i+2):(n+2)])), times = prod(x.dim[1:i]))
}
return (mat)
}
}
# Gives the corresponding rows for a permutated grid.matrix given a permutation
# x.perm of the elements of the original list x
grid.matrix.permutation = function(x,perm.col) {
restore.point("grid.matrix.permutation")
#restore.point(""grid.matrix.permutation")
stopifnot(is.list(x))
x.dim = sapply(x,length)
x.dim.perm = x.dim[perm.col]
gm = make.grid.matrix(x.dim=x.dim)
rows.perm = rep(0,NROW(gm))
nc = length(x.dim)
if (nc==1) {
return(1:NROW(gm))
}
for (mycol in 1:(nc-1)) {
rows.perm = rows.perm + (gm[,perm.col[mycol]]-1)*prod(x.dim.perm[(mycol+1):nc])
}
rows.perm = rows.perm + gm[,perm.col[nc]]
return(rows.perm)
}
# Example
# x= list(c("A","B"),c("a","b"),c("0","1"))
# perm.col = c(3,1,2)
# x.perm =x[perm.col]
# gm.x = make.grid.matrix(x)
# gm.perm = make.grid.matrix(x.perm)
# rows.perm = grid.matrix.permutation(x,perm.col)
# cbind(gm.x,gm.perm[rows.perm,])
to.list = function(ob,just.return.if.list=TRUE,return.null=TRUE) {
if (is.list(ob) & just.return.if.list)
return(ob)
li = list()
li[[1]] = ob
li
}
# My wrapper to the lattice function levelplot. Allows for some own color schemes
# The parameter focus specifies at which z range stronger color changes shall appear
sk.levelplot = function(x=NULL,y=NULL,z=NULL, xnames = NULL, ynames=NULL, grid.xyz = NULL,
col.scheme = "darkredgreen", na.col = NULL, at = NULL, at.scheme = "interval",
focus = 0, cuts=15,col.regions=NULL, xlab=NULL,ylab=NULL,
panel = panel.levelplot, zlim=NULL, reverse.colors=FALSE, ...) {
#restore.point(""sk.levelplot")
require(lattice)
if (!is.null(z)) {
z.vec = as.vector(z)
} else {
z.vec = grid.xyz[,3]
}
# Make cutpoints
if (is.null(zlim))
zlim = range(z.vec[is.finite(z.vec)])
if (is.null(at)) {
if (at.scheme == "interval") {
at.rel = seq(0,1,length=cuts)
at.rel = at.rel ^ (abs(focus)^sign(-focus))
at = zlim[1] + diff(zlim)*at.rel
} else if (at.scheme == "pretty") {
at = pretty(z.vec,cuts)
}
}
# Select colors
num.color = cuts+1
if (col.scheme == "grey") {
col.regions = grey(seq(0,1,length=num.color))
if (is.null(na.col)) {
na.col="darkblue"
na.col=hsv(1/6,1/2,1/2)
}
} else if (col.scheme == "darkredgreen" | col.scheme == "default" ) {
col.regions = c(rainbow(num.color,start=5/6, end = 1/3,v = (0.3+0.7*(1:num.color)/num.color))) # From Magenta into green
col.regions = c(rainbow(num.color,start=5/6, end = 1/4,v = (0.3+0.7*(1:num.color)/num.color))) # From Magenta into green
if (is.null(na.col))
na.col="grey"
} else if (col.scheme == "own") {
col.regions = col.regions[1:num.color]
} else {
stop(paste("col.scheme", col.scheme, " not implemented."))
}
if (reverse.colors) {
col.regions=rev(col.regions)
}
# Set NA ROWS below the lowest value and assign NA color
if (sum(!is.finite(z.vec)) > 0) {
at = c(zlim[1]-1,at)
at = c(zlim[1]-3,at)
col.regions = c(na.col,col.regions)
if (!is.null(z)) {
z[!is.finite(z)] = zlim[1]-2
} else {
grid.xyz[!is.finite(z.vec),3] = zlim[1]-2
}
}
if (!is.null(z)) {
if (!is.null(xnames))
rownames(z) = xnames
if (!is.null(ynames))
colnames(z) = ynames
row.values = 1:NROW(z); col.values = 1:NCOL(z)
if (is.numeric(x))
row.values=x
if (is.numeric(y))
column.values=y
pl = levelplot(x=z,row.values = row.values, column.values = column.values,
at=at,col.regions=col.regions,xlab=xlab,ylab=ylab,panel=panel,...)
} else {
if (is.null(xlab))
xlab = names(grid.xyz)[1]
if (is.null(ylab))
ylab = names(grid.xyz)[2]
colnames(grid.xyz) = c("x","y","z")
grid.xyz = as.data.frame(grid.xyz)
pl = levelplot(z~x*y,data=grid.xyz, at=at,col.regions=col.regions,xlab=xlab,ylab=ylab,
panel=panel,...)
}
print(pl)
}
# Helper function to discretize a continous distribution.
# F.vec is a finite vector containing the value of the cdf at M different points.
# The function generates an M dimension vector of probabilities summing up to 1
# that discretize the distribution
discretize.given.F.vec = function(F.vec) {
M = NROW(F.vec)
phi = numeric(M)
phi[1] = F.vec[1] + 0.5 * (F.vec[2]-F.vec[1])
phi[M] = 1-F.vec[M] + 0.5 * (F.vec[M]-F.vec[M-1])
if (NROW(F.vec) > 2) {
ind.left = 1:(M-2)
ind.mid = ind.left +1
ind.right = ind.left +2
phi[ind.mid] = 0.5*((F.vec[ind.mid]-F.vec[ind.left]) + (F.vec[ind.right]-F.vec[ind.mid]))
}
return(phi)
}
# Calculate numerically the expected value given a cdf
calc.mean.from.F.fun = function(F.fun,x.min=0,x.max=Inf,abs.tol = 10^(-10),
x.seq=NULL,use.num.integrate=TRUE,...) {
if (x.min >= 0 & use.num.integrate) {
H.fun = function(x,...) {1-F.fun(x,...)}
mx = integrate(H.fun,lower=x.min,upper=x.max,abs.tol=abs.tol,...)$value
return(mx)
} else {
if (is.null(x.seq)) {
x.seq = seq(x.min,x.max,length=1000)
}
F.vec = F.fun(x.seq,...)
prob = discretize.given.F.vec(F.vec)
mx = sum(prob*x.seq)
}
mx
}
all.a.get.Ue.L = function(m,L) {
if (is.null(m$LY)) {
warning("all.a.get.Ue.L: m$LY not yet initialized. You have to call solve.all.a before.")
return(NULL)
}
Ue.L.fun = function(a) {
mat = m$LY[["e"]][[a]]
if (!is.matrix(mat))
return(NA)
if (NROW(mat)==1) {
if (L < mat[1,"L"]) {
return(NA)
} else {
return(mat[1,"Ue"])
}
}
approx(mat[,"L"],mat[,"Ue"],xout=L, method="linear",
yleft=NA, yright=max(mat[,"Ue"]), rule = 1, f = 0, ties = "ordered")$y
}
ret = sapply(1:m$nA, Ue.L.fun)
ret
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.