When running this code:
library(TeachingDemos)
etxtStart(dir=getwd(), file="Nofunciona.txt")
etxtComment('Just a test')
for(i in 1:10){
cat("###",i,":\n")
my.sample = sample(100)
print(summary(my.sample))
qqnorm(my.sample)
etxtPlot(width=7.5)
}
etxtStop()
I only get a file named "Nofunciona.txt" with a text line "Just a test" and the commands to include the graphs, but nothing about the results of cat() or print(summary()), although I can see the results on the console.
If I change the loop using these two loops:
for(i in 1:10){
cat("###",i,":\n")
my.sample = sample(100)
print(summary(my.sample))
}
for(i in 1:10){
qqnorm(my.sample)
if(archivo) etxtPlot(width=7.5)
}
etxtStop()
Then I can obtain a file with the text results of cat(), and summary() and also the commands to include the graphs at the end. I know that with the last for loop I obtain ten times the same graph, that is not relevant.
It seems I cannot obtain graphical results and text results at the same time inside a for loop. Why does not the first code work?
Any idea?
Thanks.
The reason that is happening is because it is assumed that you do not want the etxtPlot command to show up in the transcript or command history, so when that function is called it sets a variable that tells the workhorse internal function (that is called by the task manager) to skip outputting the commands and results temporarily. This works correctly outside of a loop because the suppression of the output only lasts for the call to etxtPlot and everything else is properly output. The problem comes when you do this in a loop, everything done in the loop is processed in a single step (see ?addTaskCallback for the details on how things are handled), so the suppressing of the command and output from etxtPlot ends up also suppressing the commands and output from everything else in the loop.
A possible work around is to run the command:
trace(etxtPlot, edit=TRUE)
Then change the TRUE to FALSE in the second to last line of the code. Now you will see all the commands and output (including the calls to etxtPlot), but the plots will all come before the output (because the commands to include the plots are inserted at each iteration, but the other output is inserted after the loop has completed).
You might consider using the knitr package as an alternative, specifically the stitch or spin functions if you don't want to create a full template file, but just have some code processed. They don't do the realtime transcript, but deal better with automatic plot insertion.
Related
I have a readline() function in a for loop
For Simplicity let's say I have this code:
x <- character()
for (i in 1:500) x[i] <- readline('Enter Value')
How can I automatically enter input instead of manually entering it at the console 500 times?
readline() isn't intended for automatic input. From ?readline:
Description
readline reads a line from the terminal (in interactive use).
and:
Details
The prompt string will be truncated to a maximum allowed length,
normally 256 chars (but can be changed in the source code).
This can only be used in an interactive session.
Looking at ?interactive we can read the following:
An interactive R session is one in which it is assumed that there is a
human operator to interact with, so for example R can prompt for
corrections to incorrect input or ask what to do next or if it is OK
to move to the next plot.
So, basically you are trying to use readline for something it isn't intended for.
You can vectorize this command, assuming you're looking to fill the column with the same value. If that's not what you're trying to do, I'm confused as to what you want. Run my example below and say whether that's the kind of thing you're looking for
working <- iris
head(working)
working$like <- readline("Do you like this flower? ")
head(working)
I am running a rather lengthy job that I need to replicate 100 times, thus I have turned to the foreach capability in R which I then run on a 8-core cluster through a shell script. I am trying to input all of my results from each run to the same file. I have included a simplified version of my code.
cl<-makeCluster(core-1)
registerDoParallel(cl,cores=core)
SigEpsilonSq<-list()
SigLSq<-list()
RatioMat<-list()
foreach(p=1:100) %dopar%{
functions defining my variables{...}
for(i in 1:fMaxInd){
rhoSqjMatr[,i]<-1/(1+Bb[i])*(CbAdj+AbAdj*XjBarAdj+BbAdj[i]*XjSqBarAdj)/(dataZ*dataZ)
sigmaEpsSqV[i]<-mean(rhoSqjMatr[,i])
rhoSqjMatr[,i]<-rhoSqjMatr[,i]/sigmaEpsSqV[i]
biasCorrV[,i]<-sigmaEpsSqV[i]/L*gammaQl(rhoSqjMatr[,i])
Qcbar[,i]<-Qflbar-biasCorrV[,i]
sigmaExtSq[,i]<-sigmaSqExt(sigmaEpsSqV[i], rhoSqjMatr[,i])
ratioMatr[,i]<-sigmaExtSq[,i]/(sigmaL*sigmaL)#ratio (sigma_l^e)^2/(sigmaL)^2
}
sigmaEpsSqV<-as.matrix(sigmaEpsSqV)
SigEpsilonSq[[p]]<-sigmaEpsSqV
SigLSq[[p]]<-sigmaExtSq
RatioMat[[p]]<-ratioMatr
} #End of the dopar loop
stopCluster(cl)
write.csv(SigEpsilonSq,file="Sigma_Epsilon_Sq.csv")
write.csv(SigLSq,file="Sigma_L_Sq.csv")
write.csv(RatioMat,file="Ratio_Matrix.csv")
When the job completes, my .csv files are empty. I believe I'm not quite understanding how the foreach saves results and how I can access them. I would like to avoid having to merge files manually. Also, do I need to write
stopCluster(cl)
at the end of my foreach loop or do I wait until the very end? Any help would be much appreciated.
This is not how foreach works. You should look into examples. You need to use .combine, if you want to output something from your parallelized jobs.
Also, instead of this:
sigmaEpsSqV<-as.matrix(sigmaEpsSqV)
SigEpsilonSq[[p]]<-sigmaEpsSqV
SigLSq[[p]]<-sigmaExtSq
RatioMat[[p]]<-ratioMatr
You have to re-write something like this:
list(as.matrix(sigmaEpsSqV),sigmaEpsSqV,sigmaExtSq,ratioMatr)
You can also use rbind, cbind, c,... to aggregate the results into one final output.
You can even your own combine function, example:
.combine=function(x,y)rbindlist(list(x,y))
The solution below should work. The output should be a list of lists. However it might be painful to retreive results and save them in the correct format. If so, you should design your own .combine function.
cl<-makeCluster(core-1)
registerDoParallel(cl,cores=core)
SigEpsilonSq<-list()
SigLSq<-list()
RatioMat<-list()
results = foreach(p=1:100, .combine=list) %dopar%{
functions defining my variables{...}
for(i in 1:fMaxInd){
rhoSqjMatr[,i]<-1/(1+Bb[i])*(CbAdj+AbAdj*XjBarAdj+BbAdj[i]*XjSqBarAdj)/(dataZ*dataZ)
sigmaEpsSqV[i]<-mean(rhoSqjMatr[,i])
rhoSqjMatr[,i]<-rhoSqjMatr[,i]/sigmaEpsSqV[i]
biasCorrV[,i]<-sigmaEpsSqV[i]/L*gammaQl(rhoSqjMatr[,i])
Qcbar[,i]<-Qflbar-biasCorrV[,i]
sigmaExtSq[,i]<-sigmaSqExt(sigmaEpsSqV[i], rhoSqjMatr[,i])
ratioMatr[,i]<-sigmaExtSq[,i]/(sigmaL*sigmaL)#ratio (sigma_l^e)^2/(sigmaL)^2
}
list(as.matrix(sigmaEpsSqV),sigmaEpsSqV,sigmaExtSq,ratioMatr)
} #End of the dopar loop
stopCluster(cl)
#Then you extract and save results
I am not a programmer and have less than a month of experience with R but have been writing simple scripts that read from external CSV files for the past week. The function below, which reads data from a CSV file, was originally more complex but I repeatedly shortened it during troubleshooting until I was left with this:
newfunction <- function(input1, input2) {
processingobject <- read.csv("processing-file.csv")
print(head(processingobject))
}
I can print both the head and the entire processingobject within the script without a problem, but after the script ends processingobject no longer exists. It never appears in the RStudio global environment pane. Shouldn't processingobject still exist after the script terminates?
The script runs without displaying any error or warning messages. I tried assigning processingobject to a second variable: processingobject2 <- processingobject but the second variable doesn't exist after the script ends either. I also tried clearing the global environment and restarting RStudio, but that did not work either. If at the prompt after the script I type processingobject I get the message "Error: object 'processingobject' not found". The CSV file itself is perfectly normal as far as I can tell.
Obviously, I must be doing something very stupid. Please help me. Thanks.
You need to use return in your function and reproducible examples are always a good idea. It makes it easier for people to help you out.
ncol<- 10
nrow<- 100
x <- matrix(runif(nrow*ncol),nrow,ncol)
write.csv(x,file="example_data.csv")
newfunction <- function(input1) {
processingobject <- read.csv("example_data.csv")
result <- apply(processingobject,2,function(x)x*input1) #doing something to csv with input
print(head(result))
return(result)
}
newcsv <-newfunction(3)
I am trying to automatically generate a number of beanplots with a forloop, and outputting them into a LaTeX document. Starting with a data frame (that successfully generates beanplots), I am using the code below. The intent is to output consecutive beanplots into the document. I am able to do this by writing a beanplot command for each desired plot (it works fine), but obviously this would be much nicer if I could do it with a forloop. However, when I try to use a forloop, instead of outputting say 9 plots, it only outputs the last plot. Any ideas on why this is? I tried using fig.keep='all' and plot.new(), neither helped. Compiling with Sweave. Thanks!
<<beanplots,fig.keep='all'>>=
#fig.keep='all' <- this did not help
suppressPackageStartupMessages(require(beanplot))
for (i in length(unique(Data[['Days']]))){
# plot.new() ## this did not help either
beanplot(Readings~FactorLevels,
data=subset(x=Data, subset=(Data[['Days']]==i)),
main=paste("Day",i,sep=" "),
cex.axis=0.7)
}
#
beanplot works with the Lattice graphics library. As such, it does not automatically produce plots when running non-interactively. You must explicitly call print() on the object returned by the call to produce a plot. Try
<<beanplots,fig.keep='all'>>=
#fig.keep='all' <- this did not help
suppressPackageStartupMessages(require(beanplot))
for (i in unique(Data[['Days']])){
# plot.new() ## this did not help either
print(beanplot(Readings~FactorLevels,
data=subset(x=Data, subset=(Data[['Days']]==i)),
main=paste("Day",i,sep=" "),
cex.axis=0.7))
}
#
I want to see the contents of a dataframe that is created inside a function after the dataframe gets created.
Let's say the dataframe is called df in the function. If I just include a line of code like this:
df
I don't get any display to the console. I would get the dump of the dataframe contents outside a function.
Thanks
In an interactive session, when you type the name of an object, like df, R implicitly prints() the object using an appropriate method. It is as if you'd typed print(df), without you actually having to type all those extra characters.
However, there are a few places that this automatic printing is not active
As you found out, this is not active within functions,
Within loops, such a for, while etc.,
When you source a script.
In such cases, you need to explicitly print() an object.
This often catches people out with lattice and ggplot2 plots, which need to be print()ed to get them drawn on the device. but in general use, the user never has to explicitly print() these plots to get something drawn.
You're expecting it to print out because when you type the name of an object into R's shell, you have the representation of the object helpfully echoed back to you. Inside a function, this doesn't happen unless you explicitly tell R to print the information.
If print(df) doesn't work, look for buffered output and be sure it's turned off.
When you type a variable name in the console and hit enter, R silently passes that variable to print. In order to get the same effect from inside a function, you need to explicitly print. In your case:
print(df)
df <- data.frame(x = rpois(100,80))
print_me <- function(x){
print(x)
}
print_me(df)