Output of hints function from hints package in R - r

The following code has been taken from document of hints package. Last line of this code is throwing error.
library(hints)
m <- lm(BOD)
hints(m)
library(xtable)
xtable(hints(m))
The error is
Error in UseMethod("xtable") :
no applicable method for 'xtable' applied to an object of class "hints"
I wonder how to get hints function output to use in knitr or sweave document with xtable function.

It looks like xtable.hints is provided by the package but isn't properly exported so you can't actually use it. It's a fairly simple function though and the easiest solution would probably be to just copy the source and make your own function that does the exact same thing.
xtable.hints <- function(x, align = "llll", ...){
x <- as.data.frame(x$results[, c(2, 1, 3)])
colnames(x) <- c("Package", "Function", "Task")
xtable(x, align = align, ...)
}
x <- 1:10
y <- rnorm(10)
o <- lm(y~x)
xtable(hints(o)) # now it works

Related

gridsvg does not work when used inside a function

I want to define a plot saving function that uses the gridsvg device from the package gridSVG.
library(ggplot2)
library(gridExtra)
mtcars$gear <- factor(mtcars$gear,levels=c(3,4,5),
labels=c("3gears","4gears","5gears"))
mtcars$am <- factor(mtcars$am,levels=c(0,1),
labels=c("Automatic","Manual"))
mtcars$cyl <- factor(mtcars$cyl,levels=c(4,6,8),
labels=c("4cyl","6cyl","8cyl"))
myPlot <- qplot(mpg, data=mtcars, geom="density", fill=gear, alpha=I(.5),
main="Distribution of Gas Milage", xlab="Miles Per Gallon",
ylab="Density")
savePlot <- function(filename, plot, plotWidth = 15, plotHeight = 10){
gridSVG:::gridsvg(name = filename, width = plotWidth, height = plotHeight)
print(plot)
dev.off(which = dev.cur())
}
However if I then try to use the function it does not work. An error results:
savePlot("~/Desktop/myplot.svg", myPlot)
Show Traceback
Rerun with Debug
Error in eval(expr, envir, enclos) : object 'filename' not found
However if I do those steps from the console it works:
gridSVG::gridsvg(name = "~/Desktop/myPlot.svg", width = 15, height = 10)
myPlot
dev.off()
Is there a way I might be able to use the gridsvg function from within another function?
I wonder if I might be able to do it with eval from some environment.
Thanks,
Ben.
Here's a roundabout, but slightly more principled, way without sticking everything in the global environment (inspired by the scoping discussion in R Inferno):
library(gridSVG)
savePlot <- function(filename, plot, plotWidth = 15, plotHeight = 10){
gridsvg(sys.frame(1))
print(plot)
grid.export(filename)
grDevices::dev.off(which = dev.cur())
}
sys.frame(1) gives us the evaluation frame of the parent context (there's an ok explanation here for all variations on functions that access the call stack).
I separated out the call to grid.export() from the call to dev.off(), because essentially all the dev.off from gridSVG does is call grid.export, then call the grDevices::dev.off. This also lets us explicitly feed the file name to grid.export.
How curious. gridsvg seems to have an eval(fncall[[i]]) step where it walks through all the arguments and assigns them, and it must be looking in the wrong environment or something?? I am not sure if this is a problem with the gridSVG package; eval-semantics always confuse me.
Here's a workaround: if you make sure the argument -values- get passed to gridsvg (rather than the argument names) it works, though I agree this isn't particularly elegant. And you have to explicitly library(gridSVG).
library(gridSVG)
savePlot <- function(filename, plot, plotWidth = 15, plotHeight = 10){
eval(call('gridsvg', name=filename, width=plotWidth, height=plotHeight))
print(plot)
dev.off(which = dev.cur())
}
All it does is essentially call gridsvg with width=15 rather than width=plotWidth and so on.

Exclude Node in semPaths {semPlot}

I'm trying to plot a sem-path with R.
Im using an OUT file provinent from Mplus with semPaths {semPLot}.
Apparently it seems to work, but i want to remove some latent variables and i don't know how.
I am using the following syntax :
Out from Mplus : https://www.dropbox.com/s/vo3oa5fqp7wydlg/questedMOD2.out?dl=0
outfile1 <- "questedMOD.out"
```
semPaths(outfile1,what="est", intercepts=FALSE, rotation=4, edge.color="black", sizeMan=5, esize=TRUE, structural="TRUE", layout="tree2", nCharNodes=0, intStyle="multi" )
There may be an easier way to do this (and ignoring if it is sensible to do it) - one way you can do this is by removing nodes from the object prior to plotting.
Using the Mplus example from your question Rotate Edges in semPaths/qgraph
library(qgraph)
library(semPlot)
library(MplusAutomation)
# This downloads an output file from Mplus examples
download.file("http://www.statmodel.com/usersguide/chap5/ex5.8.out",
outfile <- tempfile(fileext = ".out"))
# Unadjusted plot
s <- semPaths(outfile, intercepts = FALSE)
In the above call to semPaths, outfile is of class character, so the line (near the start of code for semPaths)
if (!"semPlotModel" %in% class(object))
object <- do.call(semPlotModel, c(list(object), modelOpts))
returns the object from semPlot:::semPlotModel.mplus.model(outfile). This is of class "semPlotModel".
So the idea is to create this object first, amend it and then pass this object to semPaths.
# Call semPlotModel on your Mplus file
obj <- semPlot:::semPlotModel.mplus.model(outfile)
# obj <- do.call(semPlotModel, list(outfile)) # this is more general / not just for Mplus
# Remove one factor (F1) from object#Pars - need to check lhs and rhs columns
idx <- apply(obj#Pars[c("lhs", "rhs")], 1, function(i) any(grepl("F1", i)))
obj#Pars <- obj#Pars[!idx, ]
class(obj)
obj is now of class "semPlotModel" and can be passed directly to semPaths
s <- semPaths(obj, intercepts = FALSE)
You can use str(s) to see the structure of this returned object.
Assuming that you use the following sempath code to print your SEM
semPaths(obj, intercepts = FALSE)%>%
plot()
you can use the following function to remove any node by its label:
remove_nodes_and_edges <- function(semPaths_obj,node_tbrm_vec){
relevent_nodes_index <- semPaths_obj$graphAttributes$Nodes$names %in% node_tbrm_vec
semPaths_obj$graphAttributes$Nodes$width[relevent_nodes_index]=0
semPaths_obj$graphAttributes$Nodes$height[relevent_nodes_index]=0
semPaths_obj$graphAttributes$Nodes$labels[relevent_nodes_index]=""
return(semPaths_obj)
}
and use this function in the plotting pipe in the following way
semPaths(obj, intercepts = FALSE) %>%
remove_nodes_and_edges(c("Y1","Y2","Y3")) %>%
plot()

How to plot(object), when <object> is user defined?

I have written a function that draws some plots, and returns a list, similar in style to the following format:
myfun <- function(x, y){
plot(x, y)
points(x+1, y+1)
abline(v=x[1])
mylist <- list(x=x,y=y,line=x[1])
return(mylist)
}
This works fine. However, in R, one generally plots from functions in the following way:
x <- rnorm(100)
y <- rnorm(100)
lin <- lm(x~y)
plot(lin)
i.e., one creates an object using the function, then uses plot(object) to get the plot. How can I set up my function to behave in this way? I've had a look at a few guides to writing R packages (including hadley's), but I couldn't find reference to this problem.
I would like to create this functionality so I can upload what I've created to CRAN or R-Forge.
You could create your own S3 class for it (
R provides a lot of object oriented systems (S3, S4, R5, R.oo, ...), see also: http://adv-r.had.co.nz/OO-essentials.html):
# create an object with an own class
lin = list(x=rnorm(100), y=rnorm(100))
class(lin) = "mylin"
# overload plotting function
plot.mylin = function(l) {
plot(l$x, l$y)
points(l$x+1, l$y+1, col=2)
abline(v=l$x[1])
}
# run it
plot(lin)

How to combine do.call() plot() and expression()

I am getting an error when I try and combine using expression with do.call and plot.
x <- 1:10
y <- x^1.5
I can get the plot I want by using only the plot function:
plot(y~x,xlab=expression(paste("Concentration (",mu,"M)")))
However, I would like to implement my plot using do.call. I have a really long list of parameters stored as a list, p. However, when I try and pass the list to do.call I get the following error:
p <- list(xlab=expression(paste("Concentration (",mu,"M)")))
do.call(plot,c(y~x,p))
Error in paste("Concentration (", mu, "M)") :
object 'mu' not found
I also tried defining the formula explicitly in the args passed to do.call. ie. do.call(plot,c(formula=y~x,p)). I do not understand why I am getting the error - especially because the following does not give an error:
do.call(plot,c(0,p))
(and gives the desired mu character in the xaxis).
You can use alist rather then list
p <- alist(xlab=expression(paste("Concentration (",mu,"M)")))
do.call(plot,c(y~x,p))
do.call evaluates the parameters before running the function; try wrapping the expression in quote:
p <- list(xlab=quote(expression(paste("Concentration (",mu,"M)"))))
do.call("plot", c(y~x, p))
Setting quote=TRUE also works. It in effect prevents do.call() from evaluating the elements of args before it passes them to the function given by what.
x <- 1:10
y <- x^1.5
p <- list(xlab=expression(paste("Concentration (",mu,"M)",sep="")))
do.call(what = "plot", args = c(y ~ x, p), quote = TRUE)

new R user has regression trouble

I am new to R and am trying to run a regression analysis. I have constructed arbitrary vectors with the c() function to learn the plot, lm, fit, abline, and summary functions. That has worked properly, but when trying to regress imported data, I receive the following error message. I don't know what's causing the error or how to fix it. Any thought? Thanks.
library(xlsx)
Loading required package: xlsxjars
Loading required package: rJava
x <- "~/Desktop/x.xlsx"
y <- "~/Desktop/y.xlsx"
X <- read.xlsx(x,1)
Y <- read.xlsx(y,1)
dim(X)
[1] 149 1
dim(Y)
[1] 149 1
plot(X,Y)
Error in stripchart.default(x1, ...) : invalid plotting method
plot(X)
plot(Y)
Also, I don't think I understand all of the arguments accepted in the read.xlsx function. For example, if sheetindex is meant to index the sheets, wouldn't, in this example, x be 1 and y be 2? But then:
X <- read.xlsx(x,1)
Y <- read.xlsx(y,2)
Error in sheets[[sheetIndex]] : subscript out of bounds
Furthermore, the dimension is incorrect. The .xlsx file has 1 column, 150 rows, and no header.
dim(X)
[1] 149 1
When converting to a .csv file, which I don't particularly want to do b/c of the total number of .xlsx file I have, I still have the same plotting error, however the dimension seems to be correct. In this example, the number of rows and columns remain the same at 1 and 150 respectively, but there is a header.
x <- "~/Desktop/x.csv"
y <- "~/Desktop/y.csv"
X <- read.table(x, header = T)
Y <- read.table(y, header = T)
plot(X,Y)
Error in stripchart.default(x1, ...) : invalid plotting method
dim(X)
[1] 150 1
The problem is that X and Y are objects called data frames (?data.frame for details) and not vectors. the plot function is actually a wrapper around a family of other object-specific plot functions and in this case is trying to plot using stripchart(), which is causing the problem. This reproduces the problem, and fixes it:
X=data.frame(x=1:100)
Y=data.frame(y=rnorm(100,mean=1:100,sd=5))
plot(X,Y)
names(X)
names(Y)
plot(X$x, Y$y)
Assuming your data always consist of just one column, you could fix your code above by converting from a data.frame into an object of type numeric (i.e., the same sort of object as X=c(1,2,3,5)) which can be done a variety of ways
X <- unlist(read.xlsx(x,1))
Y <- unlist(read.xlsx(y,1))
or, alternatively, it's better to just havie read.xlsx() return a list instead of a data.frame
X <- read.xlsx(x,1, as.data.frame=FALSE)
Y <- read.xlsx(y,1, as.data.frame=FALSE)
Or you can just access the first column of the data.frame when you call plot
plot(X[,1], Y[,1])
See the help files for what all these functions return (e.g. ?as.numeric, ?unlist, ?names, etc.) and also see ?class, ?mode and ?typeof for querying object properties.
Furthermore, the dimension is incorrect. The .xlsx file has 1 column, 150 rows, and no header.
Header is by default TRUE, so you should specify this in your read.xlsx call.
X <- read.xlsx(x,1, header = TRUE)
Regarding the plot error:
plot(X,Y)
Error in stripchart.default(x1, ...) : invalid plotting method
read.xlsx returns data.frames, thats why the error shows up. Here is an example:
X <- data.frame(rnorm(150))
Y <- data.frame(rnorm(150))
plot(X, Y)
# Error in stripchart.default(x1, ...) : invalid plotting method
Please read carefully the read.xlsx documentation and about R object types.

Resources