Debugging - Power Calculator Functions and Plots - r

After several failed attempts at installing the CATS package (2013) and changing R versions, and what not, I decided to work with the source code from here
I created a single R script with all the R functions from the package, I
ran them, and then I had hopes this code would run to plot power in the example at the end of the following code :
super.cats<-function(RR,MAFmax=0.5,MAFmin=0.005,by=50,rep=1536,SNPs=1E6,ncases,ncontrols,ncases2,ncontrols2,alpha=0.05/SNPs,...){
powerList.O<-c()
powerList.J<-c()
powerList.R<-c()
powerList.F<-c()
power.O<-rep(0,length(RR))
power.F<-rep(0,length(RR))
power.J<-rep(0,length(RR))
power.R<-rep(0,length(RR))
MAF<-exp(seq(log(MAFmin),log(MAFmax),by=(log(MAFmax)-log(MAFmin))/by))
for(nmaf in 1:length(MAF)){
for(tal in 1:length(RR)){
if(power.F[tal]>0.995&power.R[tal]>0.995){
power.O[tal]<-1
power.R[tal]<-1
power.J[tal]<-1
power.F[tal]<-1
break
}
temp<-cats(risk=RR[tal],freq=MAF[nmaf],ncases=ncases,ncontrols=ncontrols,ncases2=ncases2,ncontrols2=ncontrols2,alpha=alpha,pimarkers=rep/SNPs,...)
power.O[tal]<-temp$P.one.study
power.J[tal]<-temp$P.joint
power.R[tal]<-temp$P.rep.study
power.F[tal]<-temp$P.first.stage
}
powerList.O<-cbind(powerList.O,power.O)
powerList.J<-cbind(powerList.J,power.J)
powerList.R<-cbind(powerList.R,power.R)
powerList.F<-cbind(powerList.F,power.F)
cat(nmaf," ")
}
cat("\n")
obs<-list(powerList.O=powerList.O,powerList.J=powerList.J,powerList.R=powerList.R,powerList.F=powerList.F,RR=RR,MAF=MAF,ncases=ncases,ncontrols=ncontrols,ncases2=ncases2,ncontrols2=ncontrols2,rep=rep,curve=F)
class(obs)<-"supercats"
return(obs)
}
##############################
if(FALSE){
#heat plot
rr<-seq(1,2,by=0.025)
c<-super.cats(rr,by=length(rr),ncases=765,ncontrols=1274,ncases2=100,ncontrols2=100,alpha=0.001,prevalence=0.01);
plot(c,main="power",file=NULL)
#curves
rr<-seq(1,3,by=0.05)
maf<-c(0.01,0.05,0.2,0.5)
c2<-curve.cats(rr,maf,ncases=765,ncontrols=1274,ncases2=100,ncontrols2=100,alpha=0.001,prevalence=0.01);
plot(c2,main="power2",ylab="Power",xlab="RR",file=NULL,col=1:4)
}
####
"cats" <-
function (freq=0.5,freq2=-1,ncases=500,ncontrols=500,ncases2=500,ncontrols2=500,risk=1.5,risk2=-1,pisamples=-1,prevalence=0.1,prevalence2=-1,additive=0,recessive=0,dominant=0,multiplicative=1,alpha=0.0000001,pimarkers=0.00316)
{ model<-c(additive,recessive,dominant,multiplicative)
if(sum(model==1)!=1)
stop("chose only one model. e.i. one model must be 1 the others 0")
if(sum(model==0)!=3)
stop("chose only one model. e.i. one model must be 1 the others 0")
if(freq<0|freq>1)
stop("freq must be between 0 and 1")
if((freq2<0|freq2>1)&freq2!=-1)
stop("freq2 must be between 0 and 1 (or undefined as -1)")
if((pisamples<0|pisamples>1)&pisamples!=-1)
stop("pisamples must be between 0 and 1")
if((prevalence2<0|prevalence2>1)&prevalence2!=-1)
stop("prevalence2 must be between 0 and 1 (or undefined as -1)")
if(alpha<0|alpha>1)
stop("alpha must be between 0 and 1")
if(prevalence<0|prevalence>1)
stop("prevalence must be between 0 and 1")
if(pimarkers<0|pimarkers>1)
stop("pimarkers must be between 0 and 1")
if(ncases!=as.integer(ncases)|ncases<0)
stop("ncases must be a positive integer")
if(ncases2!=as.integer(ncases2)|ncases2<0)
stop("ncases2 must be a positive integer")
if(ncontrols!=as.integer(ncontrols)|ncontrols<0)
stop("ncontrols must be a positive integer")
if(ncontrols2!=as.integer(ncontrols2)|ncontrols2<0)
stop("ncontrols2 must be a positive integer")
if(risk<0)
stop("risk must be positive")
if(risk2<0&risk2!=-1)
stop("risk2 must be positive(or undefined as -1)")
res<-.Call("cats",
as.double(freq),as.double(freq2),as.integer(ncases),as.integer(ncontrols),
as.integer(ncases2),as.integer(ncontrols2),as.double(risk),as.double(risk2),
as.double(pisamples),as.double(prevalence),as.double(prevalence2),
as.integer(additive),as.integer(recessive),as.integer(dominant),
as.integer(multiplicative),as.double(alpha),as.double(pimarkers))
options<-cbind(freq,freq2,ncases=ncases,ncontrols=ncontrols,ncases2=ncases2,ncontrols2=ncontrols2,risk,risk2,pisamples,prevalence,prevalence2,additive,recessive,dominant,multiplicative,alpha,pimarkers)
result<-list(P.one.study=res[1,1],P.first.stage=res[2,1],P.rep.study=res[3,1],P.joint.min=res[4,1],P.joint=res[5,1],pi=res[6,1],T.one.study=res[7,1],T.first.stage=res[8,1],T.second.stage.rep=res[9,1],T.second.stage.joint=res[10,1],E.Disease.freq.cases1=res[11,1],E.Disease.freq.controls1=res[12,1],E.Disease.freq.cases2=res[13,1],E.Disease.freq.controls2=res[14,1],options=options)
class(result)<-"CATS"
return(result)
}
curve.cats<-function(RR,MAF,rep=1536,SNPs=1E6,ncases,ncontrols,ncases2,ncontrols2,alpha=0.05/SNPs,...){
powerList.O<-c()
powerList.J<-c()
powerList.R<-c()
powerList.F<-c()
power.O<-rep(0,length(RR))
power.F<-rep(0,length(RR))
power.J<-rep(0,length(RR))
power.R<-rep(0,length(RR))
for(nmaf in 1:length(MAF)){
for(tal in 1:length(RR)){
if(power.F[tal]>0.995&power.R[tal]>0.995){
power.O[tal]<-1
power.R[tal]<-1
power.J[tal]<-1
power.F[tal]<-1
break
}
tempo<-cats(risk=RR[tal],freq=MAF[nmaf],ncases=ncases,ncontrols=ncontrols,ncases2=ncases2,ncontrols2=ncontrols2,alpha=alpha,pimarkers=rep/SNPs,...)
power.O[tal]<-tempo$Pone.study
power.J[tal]<-tempo$Pjoint
power.R[tal]<-tempo$Prep.study
power.F[tal]<-tempo$Pfirst.stage
}
powerList.O<-cbind(powerList.O,power.O)
powerList.J<-cbind(powerList.J,power.J)
powerList.R<-cbind(powerList.R,power.R)
powerList.F<-cbind(powerList.F,power.F)
cat(nmaf," ")
}
cat("\n")
obs<-list(powerList.O=powerList.O,powerList.J=powerList.J,powerList.R=powerList.R,powerList.F=powerList.F,RR=RR,MAF=MAF,ncases=ncases,ncontrols=ncontrols,ncases2=ncases2,ncontrols2=ncontrols2,rep=rep,curve=T)
class(obs)<-"supercats"
return(obs)
}
lines.cats<-function(x,type="Replication",col=NULL,lty=2,...){
if(type=="Joint")
power<-x$powerList.J
else if(type=="One")
power<-x$powerList.O
else if(type=="Replication")
power<-x$powerList.R
else if(type=="First")
power<-x$powerList.F
if(x$curve){
if(is.null(col))
col=1:length(x$MAF)
for(nmaf in 1:length(x$MAF))
lines(x$RR,power[,nmaf],col=col[nmaf],lwd=2,lty=lty)
}
else
cat("only for curves \n")
}
rr <- seq(1,2,by=0.05)
maf <- c(0.05,0.1,0.2,0.5)
c2 <- curve.cats(rr,maf,ncases=600,ncontrols=600,ncases2=600,ncontrols2=600, alpha=0.000001,prevalence=0.01);
plot(c2,type="One",main="power2",ylab="Power",xlab="RR",file=NULL,col=1:4)
lines.cats(c2,type="Replication",lty=3)
lines.cats(c2,type="Joint",lty=2)
lines.cats(c2,type="First",lty=4)
legend("left",c("One stage","Joint","Relication","First Stage"),lty=1:4,bty="n")
###
lines.cats<-function(x,type="Replication",col=NULL,lty=2,...){
if(type=="Joint")
power<-x$powerList.J
else if(type=="One")
power<-x$powerList.O
else if(type=="Replication")
power<-x$powerList.R
else if(type=="First")
power<-x$powerList.F
if(x$curve){
if(is.null(col))
col=1:length(x$MAF)
for(nmaf in 1:length(x$MAF))
lines(x$RR,power[,nmaf],col=col[nmaf],lwd=2,lty=lty)
}
else
cat("only for curves \n")
}
####
plot.supercats<-function(x,type="Joint",file="power.pdf",col=NULL,main=paste("POWER N=",x$ncases,":",x$ncontrols,",",x$ncases2,":",x$ncontrols2," rep=",x$rep,sep=""),...){
if(type=="Joint")
power<-x$powerList.J
else if(type=="One")
power<-x$powerList.O
else if(type=="Replication")
power<-x$powerList.R
else if(type=="First")
power<-x$powerList.F
if(!is.null(file))
pdf(file)
#curve
if(x$curve){
if(is.null(col))
col=1:length(x$MAF)
plot(x$RR,power[,1],ylim=c(0,1),main=main,col="transparent",...)
for(nmaf in 1:length(x$MAF)){
lines(x$RR,power[,nmaf],col=col[nmaf],lwd=2)
}
legend(min(x$RR),1,paste("MAF=",x$MAF),col=col,lwd=2,bty="n")
}
else{
#image
if(is.null(col))
col=heat.colors(80)
image(x$RR,x$MAF,power,col=col,main=main,log="y",ylim=c(0.005,.5),ylab="MAF",xlab="RR",...)
legend("topright",paste(1:10*10,"%"),fill=col[1:10*8],bty="n")
}
if(!is.null(file))
dev.off()
}
####
.onLoad=function(libname, pkgname)
{
library.dynam("CATS", pkgname, libname)
}
.onUnload=function(libpath)
{
library.dynam.unload("CATS", libpath)
}
####
"summary.CATS" <-
function(object, ...){
if (!inherits(object, "CATS"))
stop("Not an object of class CATS!")
cat("Options \n")
ob<-t(object$options)
colnames(ob)<-"chosen"
print(ob)
cat("Recommended thresholds:")
print(structure(list("One stage Design"=object$T.one.study,"Stage 1 Threshold"=object$T.first.stage,"Replication Threshold"=object$T.second.stage.rep,"Joint Analysis Threshold"=object$T.second.stage.joint),class="power.htest"))
cat("Eobjectpected disesase allele frequencies")
print(structure(list("Cases in stage 1"=object$E.Disease.freq.cases1,"Controls in stage 1 "=object$E.Disease.freq.controls1,"Cases in stage 2"=object$E.Disease.freq.cases2,"Controls in stage 2"=object$E.Disease.freq.controls2),class="power.htest"))
cat("Expected Power is:")
print(structure(list("For a one-stage study" = signif(object$P.one.study,
3), "For first stage in two-stage study" = signif(object$P.first.stage,
3), "For second stage in replication analysis" = signif(object$P.rep.study,
3), "For second stage in a joint analysis" = signif(object$P.joint,
3), pi = signif(object$pi, 3)), class = "power.htest"))
}
###
"print.CATS" <-
function(x, ...){
if(!inherits(x,"CATS"))
stop("Not an object of class CATS!")
cat("Expected Power is;\n")
print(structure(list("For a one-stage study"=signif(x$P.one.study,3),"For first stage in two-stage study"=signif(x$P.first.stage,3),"For second stage in replication analysis"=signif(x$P.rep.study,3),"For second stage in a joint analysis"=signif(x$P.joint,3),"pi"=signif(x$pi,3)),class="power.htest"))
}
###
"cats" <-
function (freq=0.5,freq2=-1,ncases=500,ncontrols=500,ncases2=500,ncontrols2=500,risk=1.5,risk2=-1,pisamples=-1,prevalence=0.1,prevalence2=-1,additive=0,recessive=0,dominant=0,multiplicative=1,alpha=0.0000001,pimarkers=0.00316)
{
model<-c(additive,recessive,dominant,multiplicative)
if(sum(model==1)!=1)
stop("chose only one model. e.i. one model must be 1 the others 0")
if(sum(model==0)!=3)
stop("chose only one model. e.i. one model must be 1 the others 0")
if(freq<0|freq>1)
stop("freq must be between 0 and 1")
if((freq2<0|freq2>1)&freq2!=-1)
stop("freq2 must be between 0 and 1 (or undefined as -1)")
if((pisamples<0|pisamples>1)&pisamples!=-1)
stop("pisamples must be between 0 and 1")
if((prevalence2<0|prevalence2>1)&prevalence2!=-1)
stop("prevalence2 must be between 0 and 1 (or undefined as -1)")
if(alpha<0|alpha>1)
stop("alpha must be between 0 and 1")
if(prevalence<0|prevalence>1)
stop("prevalence must be between 0 and 1")
if(pimarkers<0|pimarkers>1)
stop("pimarkers must be between 0 and 1")
if(ncases!=as.integer(ncases)|ncases<0)
stop("ncases must be a positive integer")
if(ncases2!=as.integer(ncases2)|ncases2<0)
stop("ncases2 must be a positive integer")
if(ncontrols!=as.integer(ncontrols)|ncontrols<0)
stop("ncontrols must be a positive integer")
if(ncontrols2!=as.integer(ncontrols2)|ncontrols2<0)
stop("ncontrols2 must be a positive integer")
if(risk<0)
stop("risk must be positive")
if(risk2<0&risk2!=-1)
stop("risk2 must be positive(or undefined as -1)")
res<-.Call("cats",
as.double(freq),as.double(freq2),as.integer(ncases),as.integer(ncontrols),
as.integer(ncases2),as.integer(ncontrols2),as.double(risk),as.double(risk2),
as.double(pisamples),as.double(prevalence),as.double(prevalence2),
as.integer(additive),as.integer(recessive),as.integer(dominant),
as.integer(multiplicative),as.double(alpha),as.double(pimarkers),PACKAGE="CATS")
options<-cbind(freq,freq2,ncases=ncases,ncontrols=ncontrols,ncases2=ncases2,ncontrols2=ncontrols2,risk,risk2,pisamples,prevalence,prevalence2,additive,recessive,dominant,multiplicative,alpha,pimarkers)
result<-list(P.one.study=res[1,1],P.first.stage=res[2,1],P.rep.study=res[3,1],P.joint.min=res[4,1],P.joint=res[5,1],pi=res[6,1],T.one.study=res[7,1],T.first.stage=res[8,1],T.second.stage.rep=res[9,1],T.second.stage.joint=res[10,1],E.Disease.freq.cases1=res[11,1],E.Disease.freq.controls1=res[12,1],E.Disease.freq.cases2=res[13,1],E.Disease.freq.controls2=res[14,1],options=options)
class(result)<-"CATS"
return(result)
}
#### EXAMPLE
rr<-seq(1,2,by=0.05)
maf<-c(0.05,0.1,0.2,0.5)
c2<-curve.cats(rr,maf,ncases=600,ncontrols=600,ncases2=600,
ncontrols2=600,alpha=0.000001,prevalence=0.01)
plot(c2,type="One",main="power2",ylab="Power",xlab="RR",file=NULL,col=1:4)
lines.cats(c2,type="Replication",lty=3)
lines.cats(c2,type="Joint",lty=2)
lines.cats(c2,type="First",lty=4)
legend("left",c("One stage","Joint","Relication","First Stage"),lty=1:4,bty="n")
But I get the following error:
Error in .Call("cats", as.double(freq), as.double(freq2), as.integer(ncases), : "cats" not available for .Call() for package "CATS" Called from: cats(risk = RR[tal], freq = MAF[nmaf], ncases = ncases, ncontrols = ncontrols,
ncases2 = ncases2, ncontrols2 = ncontrols2, alpha = alpha,
pimarkers = rep/SNPs, ...)
I have tried to tinker with the code, but the more I change it, the more errors appear. At this point, I would appreciate any kind of help.
Update on what I get when installing the package from R:
install.packages("CATS_1.02.tar.gz")
Warning in install.packages : package ‘CATS_1.02.tar.gz’ is not available (for R version 3.4.1)
library(CATS) Error in library(CATS) : there is no package called ‘CATS’
Update: Error when installing from command line using R CMD INSTALL CATS_1.02.tar.gz :
adris-imac:Desktop gwallace$ R CMD INSTALL CATS_1.02.tar.gz
* installing to library ‘/Library/Frameworks/R.framework/Versions/3.4/Resources/library’
* installing *source* package ‘CATS’ ...
** libs clang -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG -I/usr/local/include -fPIC -Wall -g -O2 -c CATS.c -o CATS.o In file included from CATS.c:4: ./cats.h:196:27: warning: '&&' within '||' [-Wlogical-op-parentheses] if (z > LOWER_TAIL_ONE && !upper || z > UPPER_TAIL_ZERO)
~~~~~~~~~~~~~~~~~~~^~~~~~~~~ ~~ ./cats.h:196:27: note: place parentheses around the '&&' expression to silence
this warning if (z > LOWER_TAIL_ONE && !upper || z > UPPER_TAIL_ZERO)
^
( ) CATS.c:86:7: error: non-void function 'cats' should return a value
[-Wreturn-type]
return ;
^ CATS.c:106:7: error: non-void function 'cats' should return a value
[-Wreturn-type]
return ;
^ CATS.c:133:7: error: non-void function 'cats' should return a value
[-Wreturn-type]
return ;
^ 1 warning and 3 errors generated. make: *** [CATS.o] Error 1 ERROR: compilation failed for package ‘CATS’
* removing ‘/Library/Frameworks/R.framework/Versions/3.4/Resources/library/CATS’ adris-imac:Desktop gwallace$

It would appear the code is breaking on:
res<-.Call("cats",
as.double(freq),as.double(freq2),as.integer(ncases),as.integer(ncontrols),
as.integer(ncases2),as.integer(ncontrols2),as.double(risk),as.double(risk2),
as.double(pisamples),as.double(prevalence),as.double(prevalence2),
as.integer(additive),as.integer(recessive),as.integer(dominant),
as.integer(multiplicative),as.double(alpha),as.double(pimarkers))
.Call is used to call external C/C++ code:
https://stat.ethz.ch/R-manual/R-devel/library/base/html/CallExternal.html
Without this code the R script will not work.
Also I tested installation of the package, and it seems to install fine:
> install.packages("CATS_1.02.tar.gz")
> library(CATS)
> R.version
platform x86_64-redhat-linux-gnu
arch x86_64
os linux-gnu
system x86_64, linux-gnu
status
major 3
minor 4.1
year 2017
month 06
day 30
svn rev 72865
language R
version.string R version 3.4.1 (2017-06-30)
nickname Single Candle
> CATS::cats()
$P.one.study
[1] 0.961869
$P.first.stage
[1] 0.9806984
$P.rep.study
[1] 0.8297875
$P.joint.min
[1] 0.9999998
$P.joint
[1] 0.9529604
$pi
[1] 0.5
$T.one.study
[1] 5.326724
$T.first.stage
[1] 2.951729
$T.second.stage.rep
[1] 4.000192
$T.second.stage.joint
[1] 5.30794
$E.Disease.freq.cases1
[1] 0.6
$E.Disease.freq.controls1
[1] 0.4888889
$E.Disease.freq.cases2
[1] 0.6
$E.Disease.freq.controls2
[1] 0.4888889
$options
freq freq2 ncases ncontrols ncases2 ncontrols2 risk risk2 pisamples prevalence prevalence2 additive recessive dominant multiplicative alpha pimarkers
[1,] 0.5 -1 500 500 500 500 1.5 -1 -1 0.1 -1 0 0 0 1 1e-07 0.00316
attr(,"class")
[1] "CATS"
UPDATE
Based on latest clang error maybe try:
R CMD INSTALL --configure-args="CFLAGS=-Wno-return-type CXXFLAGS=-Wno-return-type" CATS_1.02.tar.gz
UPDATE 2
Also try to add the following to ~/.R/Makevars:
CFLAGS=-Wno-return-type
CXXFLAGS=-Wno-return-type
Then re-install package:
R CMD INSTALL --clean --preclean CATS_1.02.tar.gz

Related

Troubleshooting RStata with StataBE 17; Error in seq.int(cutpoints[1] + 1, cutpoints[2] - 1) : 'from' must be a finite number

Using the package RStata in R-Studio with StataBE 17 on Mac OS yields a issue with cutpoints, that has not been resolved.
Reference: Another "Error in seq.int(cutpoints[1] + 1, cutpoints[2] - 1) : 'from' must be a finite number" problem · Issue #28 · lbraglia/RStata · GitHub
# Load Packages
install.packages("RStata")
library(RStata)
# Set Path & Version
options("RStata.StataPath" = "/Applications/Stata/StataBE.app/Contents/MacOS/StataBE")
options("RStata.StataVersion" = 17.0)
# Test Generic Code
stata("di 2+2")
--------------------
> stata("di 2+2")
Error in seq.int(cutpoints[1] + 1, cutpoints[2] - 1) :
'from' must be a finite number
I have tried searching online but the solutions for updating the path only seem to work on older versions of Stata. I have updated my packages and software, and tried to hard code the cutpoints.
I have not worked with this package, but a quick look suggests that you may need to point to the non-GUI, console p version of Stata:
> library(RStata)
>
> # Set Path & Version
> options("RStata.StataPath" = "/Applications/Stata/StataMP.app/Contents/MacOS/stata-mp")
> options("RStata.StataVersion" = 17.0)
>
> # Test Generic Code
> stata('di 2+2')
. di 2+2
4
I don't have BE, but here's how I found the MP path on my machine from the terminal:
$ which stata-mp
/Applications/Stata/StataMP.app/Contents/MacOS/stata-mp
Hopefully you just need to type state-be instead.

Recursion error in R (Fibonacci sequence)

So I am trying to learn R on my own and am just working through the online tutorial. I am trying to code a recursive function that prints the first n terms of the Fibonacci sequence and can't get the code to run without the error:
Error in if (nterms <= 0) { : missing value where TRUE/FALSE needed
My code does ask me for input before entering the if else statement either which I think is odd as well. Below is my code any help is appreciated.
#Define the fibonacci sequence
recurse_fibonacci <- function(n) {
# Define the initial two values of the sequence
if (n <= 1){
return(n)
} else {
# define the rest of the terms of the sequence using recursion
return(recurse_fibonacci(n-1) + recurse_fibonacci(n-2))
}
}
#Take input from the user
nterms = as.integer(readline(prompt="How many terms? "))
# check to see if the number of terms entered is valid
if(nterms <= 0) {
print("please enter a positive integer")
} else {
# This part actually calculates and displays the first n terms of the sequence
print("Fibonacci Sequence: ")
for(i in 0:(nterms - 1)){
print(recurse_fibonacci(i))
}
}
This is a problem of readline in non-interactive mode. readline does not wait for a keypress and immediately executes the next instruction. The solution below is the solution posted in this other SO post.
I post below a complete answer, with the Fibonnaci numbers function a bit modified.
recurse_fibonacci <- function(n) {
# Define the initial two values of the sequence
if (n <= 1){
n
} else{
# define the rest of the terms of the sequence using recursion
Recall(n - 1) + Recall(n - 2)
}
}
#Take input from the user
cat("How many terms?\n")
repeat{
nterms <- scan("stdin", what = character(), n = 1)
if(nchar(nterms) > 0) break
}
nterms <- as.integer(nterms)
# check to see if the number of terms entered is valid
if(nterms <= 0) {
print("please enter a positive integer")
} else {
# This part actually calculates and displays the first n terms of the sequence
print("Fibonacci Sequence: ")
for(i in 0:(nterms - 1)){
print(recurse_fibonacci(i))
}
}
This code is the contents of file fib.R. Running in a Ubuntu 20.04 terminal gives
rui#rui:~$ Rscript fib.R
How many terms?
8
Read 1 item
[1] "Fibonacci Sequence: "
[1] 0
[1] 1
[1] 1
[1] 2
[1] 3
[1] 5
[1] 8
[1] 13
rui#rui:~$
To make it work with Rscript replace
nterms = as.integer(readline(prompt="How many terms? "))
with
cat ("How many terms?")
nterms = as.integer (readLines ("stdin", n = 1))
Then you can run it as Rscript fib.R, assuming that the code is in the file fib.R in the current working directory.
Otherwise, execute it with source ("fib.R") within an R shell.
Rscript does not operate in interactive mode and does not expect any input from the terminal. Check what interactive () returns in both the cases. Rscript will return FALSE as it is non-interactive, but the same function when run within an R shell (with source ()) it will be true.
?readline mentions that it cannot be used in non-interactive mode. Whereas readLines explicitely connect to stdin.
The code works fine but you shouldn't enter it into the terminal as is. My suggestion: put the code into a script file (ending .R) and source it (get help about it with ?source but it's actually pretty straightforward).
In R-Studio you can simply hit the source button.

Calling print(ls.str()) in function affect behavior of rep

Begin a new R session with an empty environment. Write a series of functions with a parameter that is to be used as the value of the times parameter in a call to rep().
f <- function(n) {
rep("hello", times = n)
}
f(x)
One expect this to fail, and indeed one gets:
# Error in f(x) : object 'x' not found
Modify the function a bit:
f2 <- function(n) {
ls.str()
rep("hello", times = n)
}
f2(x)
As expected, it still fails:
# Error in f2(x) : object 'x' not found
Modify a bit more (to see the environment in the console):
f3 <- function(n) {
print(ls.str())
rep("hello", times = n)
}
f3(x)
I still expect failure, but instead get:
## n : <missing>
## [1] "hello"
It is as if the call to print() makes rep work as though times were set to 1.
This is not an answer, but too long to post as a comment. A minimal reproducible example is:
f3 <- function(n) {
try(get("n", environment(), inherits=FALSE))
rep("hello", times = n)
}
f3(x)
## Error in get("n", environment(), inherits = FALSE) : object 'x' not found
## [1] "hello"
The following is speculative and based on loosely examining the source for do_rep. get starts the promise evaluation, but upon not finding the "missing" symbol appears to leave the promise partially unevaluated. rep, being a primitive, then attempts to operate on n without realizing that it is a partially evaluated promise and basically that leads implicitly to the assumption that 'n == 1'.
Also, this shows that the promise is in a weird state (have to use browser/debug to see it):
f3a <- function(n) {
try(get("n", environment(), inherits=FALSE))
browser()
rep("hello", times = n)
}
f3a(x)
## Error in get("n", environment(), inherits = FALSE) : object 'x' not found
## Called from: f3a(x)
# Browse[1]> (n)
## Error: object 'x' not found
## In addition: Warning message:
## restarting interrupted promise evaluation
## Browse[1]> c
## [1] "hello"
I received earlier today a report that the bug has been fixed in R-devel and R-patched.
The issue was that the test for missingness in the R sources did not consider the case of an interrupted promise evaluation. A fix has been committed by Luke Tierney and can be seen on GitHub.
f4 <- function(n) {
print('test')
print(ls.str())
print('end test')
rep("hello", times = n)
}
f4(x)
## [1] "test"
## n : <missing>
## [1] "end test"
## [1] "hello"
There's something within print.ls_str, from Frank's test on chat the follwing code exhibit the same problem:
f6 <- function(n) {
z = tryCatch(get("n", new.env(), mode = "any"), error = function(e) e)
rep("A", n)
}
Digging a little inside R source I found the following code
# define GET_VALUE(rval) \
/* We need to evaluate if it is a promise */ \
if (TYPEOF(rval) == PROMSXP) { \
PROTECT(rval); \
rval = eval(rval, genv); \
UNPROTECT(1); \
} \
\
if (!ISNULL(rval) && NAMED(rval) == 0) \
SET_NAMED(rval, 1)
GET_VALUE(rval);
break;
case 2: // get0(.)
if (rval == R_UnboundValue)
return CAD4R(args);// i.e. value_if_not_exists
GET_VALUE(rval);
break;
}
return rval;
}
#undef GET_VALUE
I'm quite surprised this compile properly, as far as I remember (my C is quite far behind) #define doesn't allow spaces between the # and define.
After digging for that, I'm wrong, from gcc doc:
Whitespace is also allowed before and after the `#'.
So there's probably something around this part of code, but that's above my head to pinpoint what exactly.

Return 'next' and print message from a tryCatch function to skip to the next loop iteration

I want to use tryCatch() to check if packages are installed from within a loop, and then return next to break out and skip to the next iteration of the loop if the package failed to load or install. At the same time, I want to return a message to the console reporting this. I can do one, or the other, but I am having trouble figuring out how to do both at the same time. For example, this work:
package_list<-c("ggplot2", "grid", "plyr")
for(p in package_list){
# check if package can't be loaded
if(!require(p,character.only=TRUE,quietly=TRUE,warn.conflicts=FALSE)){
write(paste0("Attempting to install package: ",p), stderr())
# try to install & load the packages, give a message upon failure
tryCatch(install.packages(p,repos="http://cran.rstudio.com/"),
warning = function(e){write(paste0("Failed to install pacakge: ", p), stderr())},
error = function(e){write(paste0("Failed to install pacakge: ", p), stderr())})
tryCatch(library(p,character.only=TRUE,verbose=FALSE),
warning = function(e){write(paste0("Failed to install pacakge: ", p), stderr())},
error = function(e){write(paste0("Failed to install pacakge: ", p), stderr())})
# try to install & load the packages, skip to next loop iteration upon failure
tryCatch(install.packages(p,repos="http://cran.rstudio.com/"),warning = next)
tryCatch(library(p,character.only=TRUE,verbose=FALSE),warning = next)
}
}
But this requires running each command twice; once to fail and return a message about the failure, and then again to fail and skip to the next item in the loop.
Instead, I would much rather perform both actions with a single function, like this:
for(p in package_list){
if(!require(p,character.only=TRUE,quietly=TRUE,warn.conflicts=FALSE)){
tryCatch(install.packages(p,repos="http://cran.rstudio.com/"),
warning = function(e){print(paste("Install failed for package: ", p)); return(next)})
# ...
}
}
However, this fails because you cannot use next from within a function:
Error in value[[3L]](cond) : no loop for break/next, jumping to top level
Is there a way to both return the desired message, and issue the next command from within tryCatch() in order to perform this function?
Use message() rather than write(..., stderr()); it takes several arguments that do not have to be paste()ed together.
Use tryCatch() to return a status code, and act on the status code; the following
for (i in 1:10) {
status <- tryCatch({
if (i < 5) warning("i < 5")
if (i > 8) stop("i > 8")
0L
}, error=function(e) {
message(i, ": ", conditionMessage(e))
1L
}, warning=function(w) {
message(i, ": ", conditionMessage(w))
2L
})
if (status != 0L)
next
message("success")
}
prints
1: i < 5
2: i < 5
3: i < 5
4: i < 5
success
success
success
success
9: i > 8
10: i > 8

DEoptim stack imbalance problems

When running the following optimization task (R v.3.0.2)
library(DEoptim)
x <- seq(-6,6,length=100); y <- tanh(x)
goal <- function(par) return(1-abs(cor(x*par,y,method='spearman')))
ctrl <- DEoptim::DEoptim.control(VTR=0, trace=FALSE)
res <- DEoptim::DEoptim(goal,lower=-1,upper=1, ctrl)
I get stack imbalance warnings
Warning: stack imbalance in '<-', 14 then 13
Warning: stack imbalance in 'withVisible', 7 then 6
and unprotect() errors. If VTR is set below 0 (i.e. to a value impossible to obtain) then the problem disappears, but I'd rather not do that due to performance issues.
The result gets returned despite the errors however I fear it might be unstable/incorrect. Any ideas how to solve this?
It's a problem in the C code, not something you can fix. But it's something I can fix, and it's fixed as of revision 116 on R-Forge. Here's the patch:
Index: DEoptim/src/de4_0.c
===================================================================
--- DEoptim/src/de4_0.c (revision 115)
+++ DEoptim/src/de4_0.c (working copy)
## -423,7 +423,6 ##
/*------Trial mutation now in t_tmpP-----------------*/
/* evaluate mutated population */
- if(i_iter > 1) UNPROTECT(1); // previous iteration's sexp_t_tmpC
PROTECT(sexp_map_pop = popEvaluate(l_nfeval, sexp_t_tmpP, fnMap, rho, 0));
memmove(REAL(sexp_t_tmpP), REAL(sexp_map_pop), i_NP * i_D * sizeof(double));
UNPROTECT(1); // sexp_map_pop
## -458,6 +457,7 ##
}
} /* End mutation loop through ensemble */
+ UNPROTECT(1); // sexp_t_tmpC
if (d_c > 0) { /* calculate new meanCR and meanF */
meanCR = (1-d_c)*meanCR + d_c*goodCR;
## -555,7 +555,7 ##
*gt_bestC = t_bestC;
PutRNGstate();
- UNPROTECT(P+1); // +1 is for last iteration's sexp_t_tmpC
+ UNPROTECT(P);
}
I am using revision 118 and I had a similar problem:
Warning: stack imbalance in '.Call', 13 then 12
Warning: stack imbalance in '<-', 11 then 10
That happened when I inverted the sign of the variable that the objective function returns, from return(-var) to return(var). The way around it was just to change the sign in the code before.

Resources