How to create a demo for a presentation tutorial? - r

I want to prepare a demo (that will play sequentially in clicks) for a presentation tutorial...Can somebody help me how can I write a demo, suppose the following are steps in the demo...
#start
set.seed(1345)
x1 <- sample(letters[1:10], 5)
x1
sort(x1)
x <- sample(1:10, 5)
y <- sample(c(11:20), 5)
require(lattice)
plot(x,y)
z <- rnorm(5, 1, 0.5)
dataframe <- data.frame(x, y, z)
model1 <- lm(y ~x)
aov(model1)
#end
Sorry I could find a solution after hours and days of search. I appreciate your help.

Another way to do it:
Save your script in a file (demo.R)
Edit the script and sprinkle it with pause() in strategic places
In R, define pause <- function() invisible(readline())
Run the script with source("demo.R", echo=TRUE)
It will then print & run your commands and stop and wait for input at the sprinkled pause(). Just hit <Enter> to continue.
EDIT: I don't know a good way to hide the pause() statement. A possible way would be to copy the code for source() and modify it to skip printing calls to pause(), but that's a little overkill I think...
...but you could rename the pause function to anything you like - including '....', but you still need to call it like this: ....()
Hmmm. Maybe something like this:
'....' <- function(...) invisible(readline())
Then sprinkle your script with either:
....('Press Enter to continue')
# Or
....(Press_Enter_to_continue)
Another possibility if you rename the pause function to Pausing...:
Pausing...(Press_Enter)

A hacky way of doing what you want is:
Save commands as a script, eg testDemo.r
Copy into and existing package's demo folder, eg <Library>/base/demo
Run with demo(testDemo,package="base")
But it pauses in pages rather than by command. Ultimately though, you may want to create your own package to contain custom demos.
Edit
It seems the code for demo is mainly for checking that a demo exists, and the core is quite simple:
op <- options(device.ask.default=TRUE)
source("testDemo.r",echo=TRUE,max.deparse.length=Inf,keep.source=TRUE)
options(op)
Note that any pausing is only done by the presence of graphics, not any length of echoed text, as is actually the case with demo.

Related

R not remembering objects written within functions

I'm struggling to clearly explain this problem.
Essentially, something has seemed to have happened within the R environment and none of the code I write inside my functions are working and not data is being saved. If I type a command line directly into the console it works (i.e. Monkey <- 0), but if I type it within a function, it doesn't store it when I run the function.
It could be I'm missing a glaring error in the code, but I noticed the problem when I accidentally clicked on the debugger and tried to excite out of the browser[1] prompt which appeared.
Any ideas? This is driving me nuts.
corr <- function(directory, threshold=0) {
directory <- paste(getwd(),"/",directory,"/",sep="")
file.list <- list.files(directory)
number <- 1:length(file.list)
monkey <- c()
for (i in number) {
x <- paste(directory,file.list[i],sep="")
y <- read.csv(x)
t <- sum(complete.cases(y))
if (t >= threshold) {
correl <- cor(y$sulfate, y$nitrate, use='pairwise.complete.obs')
monkey <- append(monkey,correl)}
}
#correl <- cor(newdata$sulfate, newdata$nitrate, use='pairwise.complete.obs')
#summary(correl)
}
corr('specdata', 150)
monkey```
It's a namespace issue. Functions create their own 'environment', that isn't necessarily in the global environment.
Using <- will assign in the local environment. To save an object to the global environment, use <<-
Here's some information on R environments.
I suggest you give a look at some tutorial on using functions in R.
Briefly (and sorry for my horrible explanation) objects that you define within functions will ONLY be defined within functions, unless you explicitly export them using (one of the possible approaches) the return() function.
browser() is indeed used for debugging, keeps you inside the function, and allows you accessing objects created inside the function.
In addition, to increase the probability to have useful answers, I suggest that you try to post a self-contained, working piece of code allowing quickly reproducing the issue. Here you are reading some files we have no access to.
It seems to me you have to store the output yourself when you run your script:
corr_out <- corr('specdata', 150)

How to read results from one R script to another

Is there anyway I can store the results of one variable in one R script, and make them available to another R script?
I have this basic script in one file:
B5b=fit(y~.,d_treino_both,model="randomforest",task="class")
P5b=predict(B5b,d_teste)
x=d_teste$y
m5b=mmetric(x,P5b,metric=c("ACC","ACCLASS","CONF", "ROC"))
mgraph(x,P5b,graph= "ROC", baseline=TRUE)
print(m5b)
P5b
Then, I want to make the resuts of P5b variable available to another script.
Any help?
Not sure if this is what you are looking for. I think one way you can do that is to source the script1 in script2. I would do something like this and remove any additional variables using rm.
source("script1.R")
Perhaps you could try something with dput and the clipboard. Basically, this is just copying the dput of an object to the clipboard and then evaluating the clipboard in the second script. Note that you cannot use the clipboard in the meantime.
# first script
obj <- capture.output(dput(matrix(1:100, 10, 10)))
writeClipboard(str = obj)
# second script
obj2 <- eval(parse(text = readClipboard()))

Is it a bad idea to get name of script using sys.frame(1)$ofile?

I've been searching for a while for a way to get the name of the currently executed script. Most answers I've seen were one of:
Use commandArgs() - but this won't work for me because in RStudio commandArgs() does not return the filepath
Define the name of the script as the top line and then use that in the rest of the script
I saw one mention of sys.frames() and found out that I can use sys.frame(1)$ofile to get the name of the currently executing script. I don't know much about these kinds of functions, so can anyone advise me if that's a bad a idea or when it can fail me?
Thanks
The problem is that R does't really run code as "scripts." When you "source" a file, it's basically like re-typing the contents of the file at the console. The exception is that functions can keep track of where they were sourced from.
So if you had a file like mycode.R that had
fn <- function(x) {
x + 1 # A comment, kept as part of the source
}
and then you can do
source("mycode.R")
getSrcFilename(fn)
# [1] "mycode.R"
so in order to do that you just need to know a name of the function in the file. You could also make a function like this
gethisfilename <- function(z) {
x<-eval(match.call()[[1]])
getSrcFilename(x)
}
Assuming it's also in mycode.R, you can do
source("mycode.R")
gethisfilename()
# [1] "mycode.R"
Actually I think it is a bad idea, as I explained in my comment here: if you place this code in file1.R and then you source("file1.R") from file2.R, this will actually return "file2.R" instead of "file1.R", where it is called from!
So, to overcome this, you need to use sys.frames() and go for this solution: https://stackoverflow.com/a/1816487/684229
this.file.name <- function () # https://stackoverflow.com/a/1816487
{
frame_files <- lapply(sys.frames(), function(x) x$ofile)
frame_files <- Filter(Negate(is.null), frame_files)
frame_files[[length(frame_files)]]
}
Then you can use this.file.name() in any script and it will return the correct answer! It doesn't depend how deep is the "source-stack". And also it doesn't depend where is the this.file.name() function defined. It will return the information of the source file where it's called from.
(and apart from MrFlick's interesting solution, this doesn't need any function to be defined in the file)

How to view results in a file using a function and *apply?

I like to pop out results in a window so that they're easier to see and find (e.g., they don't get lost as the console continues to scroll). One way to do this is to use sink() and file.show(). For example:
y <- rnorm(100); x <- rnorm(100); mod <- lm(y~x)
sink("tempSink", type="output")
summary(mod)
sink()
file.show("tempSink", delete.file=T, title="Model summary")
I commonly do this to examine model fits, as above, but also for a wide variety of other functions and objects, such as: summary(data.frame), anova(model1, model2), table(factor1, factor2). These are common, but other situations can arise as well. The point here is that both the nature of the function and the object can vary.
It is somewhat tedious to type out all of the above every time. I would like to write a simpler function that I can call, something like the following would be nice:
sinkShow <- function(obj, fun, title="output") {
sink("tempSink", type="output")
apply(obj, ?, fun)
sink()
file.show("tempSink", delete.file=T, title=title)
}
Clearly, this doesn't work. There are several issues. First, how would you do this so that it won't crash with the wrong type of object or function without having to have a list of conditional executions (i.e., if(is.list(obj) { lapply...). Second, I'm not sure how to handle the margin argument. Lastly, this doesn't work even when I try simple, contrived examples where I know that everything is set appropriately, so there seems to be something fundamentally wrong.
Does anyone know how such a situation can be handled simply and easily? I'm not new to R, but I've never been formally taught it; I've picked up tricks in an ad-hoc manner, i.e., I'm not a very sophisticated R programmer. Thanks.
Rather than use apply I think you want do.call. Make sure to wrap it in a print since it is inside of a function.
Here is one possible implementation:
sinkShow <- function( obj, fun, title='Output', ...) {
file <- tempfile()
args <- c(list(obj),list(...))
capture.output( do.call( fun, args ), file=file )
file.show(file, delete.file=TRUE, title=title)
}
Though it should probably be renamed since I skipped using sink as well. I might modify this a bit and put it into the TeachingDemos package.
Use page. Here's some sample models:
d <- data.frame(y1=rnorm(100), y2=rnorm(100), x=rnorm(100))
mod <- lm(y1~x, data=d)
mods <- list(mod1=lm(y1~x, data=d), mod2=lm(y2~x, data=d))
And here's how you'd use page:
page(summary(mod), method="print")
page(lapply(mods, summary), method="print")
For my original post, which had code that turned out to be a near-reimplementation of page, see the edit history.

How Do I Stop An R gWidgets Script Exiting

I am using the gWidgets toolkit to create a GUI in an R script that is run using Rscript.
When the GUI is created, the script exits.
I can prevent this with a while(TRUE){Sys.sleep(9999)} loop at the end of the script but that seems hacky.
Is there a better way of telling R to exit only when the GUI is closed, or at least to enter the REPL once the GUI is constructed?
You might be able to adapt gbasicdialog for your needs. This constructor creates a modal container from which you can spawn other windows. Here is an example:
library(gWidgets)
options(guiToolkit="RGtk2")
require(fortunes) # just for fun
hold_it <- gbasicdialog(do.buttons=FALSE)
b <- gbutton("click me for a message", cont=hold_it, handler=function(h,...) {
gmessage(paste(fortune(), collapse="\n"), parent=hold_it)
})
visible(hold_it, TRUE)
The same works for the "tcltk" toolkit. It uses pretty much what Greg suggests can be done.
This subject may be closed but as a newbie to gwidgets, I have been confronted with. The solution given by jverzani is obviously a solution. I have chosen another one, not using any supplementary dialog, just because I don't want one, no other reason at all...
In the handler of the gwindow, after disposal I remove the variable from the environment:
handler = function(h,...) {dispose(EDFAnalysis$w); rm(w,envir=EDFAnalysis)}
where EDFAnalysis is the environment of my script... and w is the main gwindow.
Then, at the end of my script I added:
while(exists("w",EDFAnalysis)){Sys.sleep(5)}
of course, smaller value than 5 or greater value can be used. In my case, 5 s is sufficient and not for ever... :-)
The standard way of dealing with this is to request user input to continue. This one-liner will do the trick.
EDIT: readline only works under interactive use, so I've swapped it for scan, which is a little less pretty.
pause_for_input <- function()
{
message("Press ENTER to continue")
invisible(scan(n = 0, quiet = TRUE))
}
So you script should look like
#Create you GUI
#Whatever else
pause_for_input()
If you are using the tcltk package instead of gWidgets then you could possibly use the tkwait.window function from tcltk to tell the script to wait until the gui window goes away before continuing the script.
A good way to do it, I've found, is to use the gtkMain() function in the RGtk2 library. This simply keeps the main loop running until gtkMainQuit() is called.
For completeness: ozjimbob already gave the answer for a most "clean" way how to do it.
The answer of ffeschet did not work with me, neither on Unix nor on Windows.
Hence, in the main "launching" script, you have to at least have these entries:
options("guiToolkit"="RGtk2")
library(RGtk2)
library(gWidgets)
library(gWidgetsRGtk2)
StartMyGUI()
gtkMain()
In the "child" process "StartMyGUI()", your code could e.g. look like this:
StartMyGUI <- function(handler=function(h,...) {
dispose(h$obj)
}) {
window <- gwindow("Hello")
group <- ggroup(container = window)
glabel("Hello World!", container=group, expand=TRUE)
# A group to organize the buttons
button.group <- ggroup(container = group)
# Push buttons to right
addSpring(button.group)
gbutton("OK", handler=handler, container=button.group)
gbutton("Cancel", handler = function(h,...) {
dispose(window)
gtkMainQuit()
},
container=button.group)
return()
}
It is only when the user hits the "Cancel" button that gtkMainQuit() will be called, which exits the mother process in the main "launching" script.

Resources