R : "argument is missing, with no default " - r

I am running the following code to minimize a function thanks to optim() in R but I have the following message : "argument "h" is missing, with no default".
I checked on previous messages where it is said that it is often a comma before a parenthesis, but does not seem to be the case in my code.
Could you please help me to understand what to do ? Thank you very much.
Here is the code :
A<-function(t,k,h,s){
out<-exp((h-(s*s/(2*k*k)))*(B(t,k)-t)-(s*s/(4*k))*(B(t,k)^2))
return(out)
}
B<-function(t, k){
out<-(1-exp(-k*t))/k
return(out)
}
P<-function(a, b, r){
out<-a*exp(-b*r)
return(out)
}
somme<-function(k,h,s){
out<-(P(A(1,k,h,s), B(1,k), -0.002)-1.0021)^2+(P(A(2,k,h,s), B(2,k), -0.0016)-1.0036)^2+(P(A(3,k,h,s), B(3,k), -0.001)-1.0038)^2+(P(A(4,k,h,s), B(4,k), -0.0002)-1.002)^2+(P(A(5,k,h,s), B(5,k), 0.00077)-0.9976)^2+(P(A(6,k,h,s), B(6,k), 0.0019)-0.9901)^2+(P(A(7,k,h,s), B(7,k), 0.0031)-0.9796)^2+(P(A(8,k,h,s), B(8,k), 0.0044)-0.9655)^2+(P(A(9,k,h,s), B(9,k), 0.0056)-0.9494)^2+(P(A(10,k,h,s), B(10,k), 0.0067)-0.9317)^2
return(out)
}
init<-c(k=0,h=0,s=0)
result<-optim(par=init, fn=somme)
result

The documentation in help("optim") says (emphasis added by me):
fn
A function to be minimized (or maximized), with first argument the
vector of parameters over which minimization is to take place. It
should return a scalar result.
Thus, this works:
somme <- function(par){
k <- par[[1]]
h <- par[[2]]
s <- par[[3]]
out <- (P(A(1,k,h,s), B(1,k), -0.002)-1.0021)^2+
(P(A(2,k,h,s), B(2,k), -0.0016)-1.0036)^2+
(P(A(3,k,h,s), B(3,k), -0.001)-1.0038)^2+
(P(A(4,k,h,s), B(4,k), -0.0002)-1.002)^2+
(P(A(5,k,h,s), B(5,k), 0.00077)-0.9976)^2+
(P(A(6,k,h,s), B(6,k), 0.0019)-0.9901)^2+
(P(A(7,k,h,s), B(7,k), 0.0031)-0.9796)^2+
(P(A(8,k,h,s), B(8,k), 0.0044)-0.9655)^2+
(P(A(9,k,h,s), B(9,k), 0.0056)-0.9494)^2+
(P(A(10,k,h,s), B(10,k), 0.0067)-0.9317)^2
return(out)
}
init <- c(k = 1, h = 1, s = 1)
result <- optim(par = init, fn = somme)
PS: You seem to be a masochist who likes excessive typing.

Related

Target multiple variables for a function within a custom function

I would like to build a function which runs a chi square test if calc=TRUE. The problem appears to be targeting the variables used within the wtd.chi.sq function.
Thank you very much in advance.
library(weights); library(sjstats)
testfunction <- function(dta, x, y, calc=TRUE, annotate=note){
if(isTRUE(calc)){
testresult<-wtd.chi.sq(dta[[x]], dta[[y]])
return(testresult["p.value"])
}
else {
annotate <- paste0(note, "... and no calc necessary")
}
return(annotate)
}
testfunction(dta=df, x=f1, y=s12x, calc=TRUE, annotate=note)
Error in tbl_subset2(x, j = i, j_arg = substitute(i)) :
object 'f1' not found

How to solve error in while looping EM algorithm in R

my project needs the EM algorithm below, where is all the code. The error is in the while loop, which is where the hope and maximization steps are. The error message is "Error in while (abs (Elogv [r] - Elogv [r - 1])> = 1e-06) {: missing value where TRUE / FALSE needed". How do I resolve this error if the while loop contains no true and false commands, and if I have already checked in detail that there are no errors in the commands and no NA's value? Grateful for the attention, who can save me.
n=100
u<-runif(n)
QUANTIL <- function(u){
Q <- rep(NA, length(u))
for (i in 1:length(u)) {
if(u[i] < 0.2634253829){
Q[i] <- 1*tan(pi*(0.9490353482*u[i]-0.5))+0
}
if(u[i]>=0.2634253829 && u[i] < 0.7365746171){
Q[i] <- 1*qnorm(1.4428629504*u[i]-0.2214315)+0
}
if(u[i]>0.7365746171){
Q[i] <- 1*tan(pi*(0.9490353482*u[i]-0.4490353))+0
}
}
return(Q)
}
x<-QUANTIL(u)
y<-c(sort(x))
i<-seq(1,n)
v<-c(i/(n+1))
t<-QUANTIL(v)
mi<-median(y)
s<-c(y[26:73])
sigma<-sqrt(sum((s-mi)^2)/(n-1))
p=0.4731492342
alpha<-(2*t^3)/(1+t^2)^2
beta<-(1-t^2)/(1+t^2)^2
eta<-(t^4-t^2)/(1+t^2)^2
lambda<-2*t/(1+t^2)^2
gama<-(-t^2)
delta<-2*t
k<-((p*0.6930665173/sigma*sqrt(2*pi))*exp((-1/2*sigma^2)*((y-mi)^2)))/(((p*0.6930665173/sigma*sqrt(2*pi))*exp((-1/2*sigma^2)*(y-mi)^2))+((((1-p)*1.0537015317/sigma*pi))*(1/(1+((y-mi)/sigma)^2))))
r<-2
Elogv<-sum(k*((-1/2)*((y-mi)/sigma)^2))-sum(k*log(sigma*sqrt(2*pi)))-sum((1-k)*log(sigma*pi))-sum((1-k)*log(1+((y-mi)/sigma)^2))+sum(k*log(p))+(n-sum(k))*log(1-p)+log(0.6930665173)*sum(k)+log(1.0537015317)*sum(1-k)
Elogv[1]<-0
while (abs(Elogv[r]-Elogv[r-1])>=0.000001) {
w<-(2*beta-2*k*beta+k)
q<-k*delta+2*lambda*(1-k)
sigma<-(sum(y*w)*sum(q)-sum(w)*sum(y*q))/(-2*sum(alpha*(1-k))*sum(q)+sum(w)*sum(k*gama-1)+2*sum(w)*sum(eta*(1-k)))
mi<-(sum(y*w)+2*sigma*sum(alpha*(1-k)))/sum(w)
k<-((p*0.6930665173/sigma*sqrt(2*pi))*exp((-1/2*sigma^2)*((y-mi)^2)))/(((p*0.6930665173/sigma*sqrt(2*pi))*exp((-1/2*sigma^2)*(y-mi)^2))+((((1-p)*1.0537015317/sigma*pi))*(1/(1+((y-mi)/sigma)^2))))
Elogv[r]<-sum(k*((-1/2)*((y-mi)/sigma)^2))-sum(k*log(sigma*sqrt(2*pi)))-sum((1-k)*log(sigma*pi))-sum((1-k)*log(1+((y-mi)/sigma)^2))+sum(k*log(p))+(n-sum(k))*log(1-p)+log(0.6930665173)*sum(k)+log(1.0537015317)*sum(1-k)
r<-r+1
It looks to me that the length of Elogv is 1? Thus Elogv[r] has no entry (r is 2!), i.e. evaluates to NA, thus the abs(Elogv[r]-Elogv[r-1]) is NA.
You need Elogv[2] <- 0 before starting the loop?

Specify the calling function for an error message in R

I'm working on an R package where the same input-checking functions are called by multiple "actual" functions that are exported to users. If I use a simple stop() call, the error message is going to say that an error occurred in the input-checking function, which is not that useful...
I thought I'd get around this by wrapping the call to the input-checking function inside a tryCatch(), and then handling the error in the outer function. This does mostly what I want, but doesn't quite give the output that I'd like. The closest I've come is the following:
f <- function(i) {
tryCatch({
check_input(i)
}, error = function(e) stop("in f: ", e$message, call. = FALSE)
)
}
check_input <- function(i) {
if(i < 0)
stop("i is negative, value given was ", i)
}
f(-1)
# Error: in f: i is negative, value given was -1
Ideally, I'd like the error message to be
Error in f: i is negative, value given was -1
, which would be the case if stop were called within f() instead of check_input().
Here's how you can grab the name of the function from the call stack and paste it in to the error message
f <- function(i) {
check_input(i)
}
g <- function(i) {
check_input(i)
}
check_input <- function(i, from=deparse(sys.calls()[[sys.nframe()-1]][[1]])) {
getmsg <- function(m) ifelse(!is.null(from), paste0("in ", from, ": ", m), m)
if(i < 0)
stop(getmsg(paste0("i is negative, value given was ", i)), call. = FALSE)
}
f(-1)
# Error: in f: i is negative, value given was -1
g(-1)
# Error: in g: i is negative, value given was -1
You could also call check_input(i, from="otherfunction") to show whatever function name you want or check_input(i, from=NULL) to suppress the function name.

compute an integration

Here is my integrand()
integrand<-function(x,vecC)
{
as.numeric((2/(b-a))*vecC%*%as.matrix(cos((x-hat.a)
*(seq(0,N-1,length=N)*pi/(b-a)))))
}
it can produce the value. For example, for
a<-1
b<-10
vecC<-t(as.matrix(rnorm(80)))
hat.a<--1.2
N<-80
I get
> integrand(1.4,vecC)
[1] -0.3635195
but I met problem when I run the following code for integration
> integrate(function(x){integrand(x,vecC)},upper = 3.4,lower = 1)$value
and the error message is
Error in integrate(function(x) { :
evaluation of function gave a result of wrong length
In addition: Warning message:
In (x - hat.a) * (seq(0, N - 1, length = N) * pi/(b - a)) :
longer object length is not a multiple of shorter object length
If you read the help page for integrate you will see that the function passed to integrate should return a vector.
So the solution to your error is to use Vectorize like this
Define your function separately as
f <- function(x){integrand(x,vecC)}
Now define a vectorized version of this function like so
fv <- Vectorize(f,"x")
and then
integrate(fv,upper = 3.4,lower = 1)$value
will give you a result.

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.

Resources