curve() using a function with argument in R - r

ppt=function(v, tail = 0.5){
if (tail == 1){
6/pi^2/v^2
} else {
if (v < 11) {
(1-tail)*(11-v)/55
} else {tail*6/pi^2/(v-10)^2}
}
}
curve(ppt(tail = 0.2))
Error in curve(ppt(tail = 0.2)) :
'expr' must be a function, or a call or an expression containing 'x'
How should I plot a smooth curve for the function ppt() with different values of variable tail?
Thank you.

Either (1) rewrite ppt to vectorize it (not shown) or else (2) use Vectorize as shown below in which case ppt does not have to be modified. Also use this syntax.
curve(Vectorize(ppt)(x, tail = 0.2), ylab = "ppt")

Maybe the following trick?
w = 0.2
g <- function(z) ppt(z, tail = w)
curve(g)
And do not forget to replace, as #MrFlick points out in the comment:
if (v < 11) {
(1-tail)*(11-v)/55
} else {tail*6/pi^2/(v-10)^2}
by
ifelse(v < 11, (1-tail)*(11-v)/55, tail*6/pi^2/(v-10)^2)

Related

How to implement a function with a sum inside in R?

I am trying to define a function with a for loop and inside a conditional in R studio. Yesterday I was able with the help of another thread to devise this piece of code. The problem is that I want to sum the vector elements ma for any possible x, so that is inside the function l. This is a simpler case which I am trying to solve to adapt the original model. However, I do not know how to proceed.
ma<-rep(0,20)
l <- function(x, ma) {
for(i in seq_along(ma)) {
if(i %% 2 == 1) {
ma[i] <- i + x
} else {
ma[i] <- 0
}
}
return(ma)
}
My problem is that I would like to have the sum of i+x+0+i+x... for any possible x. I mean a function of the kind for any possible x.
Question:
Can someone explain to me how to implement such a function in R?
Thanks in advance!
I am going to update the original function:
Theta_alpha_s<-function(s,alpha,t,Basis){
for (i in seq_along(Basis)){
if(i%% 2==1) {Basis[i]=s*i^{-alpha-0.5}*sqrt(2)*cos(2*pi*i*t)}
else{Basis[i]=s*i^{-alpha-0.5}*sqrt(2)*sin(2*pi*i*t)}
}
return(Basis)
}
If you don't want to change the values in Basis, you can create a new vector in the function (here result) that you will return:
l = function(s,alpha,t,Basis){
is.odd = which(Basis %% 2 == 1)
not.odd = which(Basis %% 2 == 0)
result = rep(NA, length(Basis))
result[is.odd] = s*is.odd^{-alpha-0.5}*sqrt(2)*cos(2*pi*is.odd*t)
result[not.odd] = s*not.odd^{-alpha-0.5}*sqrt(2)*sin(2*pi*not.odd*t)
#return(result)
return(c(sum(result[is.odd]), sum(result[not.odd])))
}

(R) Error in optim - attempt to apply non-function, when function is defined

not sure what I'm doing wrong here. I'm trying to get a cross-validation score for a mixture-of-two-gammas model.
llikGammaMix2 = function(param, x) {
if (any(param < 0) || param["p1"] > 1) {
return(-Inf)
} else {
return(sum(log(
dgamma(x, shape = param["k1"], scale = param["theta1"]) *
param["p1"] + dgamma(x, shape = param["k2"], scale = param["theta2"]) *
1
(1 - param["p1"])
)))
}
}
initialParams = list(
theta1 = 1,
k1 = 1.1,
p1 = 0.5,
theta2 = 10,
k2 = 2
)
for (i in 1:nrow(cichlids)) {
SWS1_training <- cichlids$SWS1 - cichlids$SWS1[i]
SWS1_test <- cichlids$SWS1[i]
MLE_training2 <-
optim(
par = initialParams,
fn = llikGammaMix2,
x = SWS1_training,
control = list(fnscale = -1)
)$par
LL_test2 <-
optim(
par = MLE_training2,
fn = llikGammaMix2,
x = SWS1_test,
control = list(fnscale = -1)
)$value
}
print(LL_test2)
This runs until it gets to the first optim(), then spits out Error in fn(par, ...) : attempt to apply non-function.
My first thought was a silly spelling error somewhere, but that doesn't seem to be the case. Any help is appreciated.
I believe the issue is in the return statement. It's unclear if you meant to multiply or add the last quantity (1 - param["p1"])))) to the return value. Based on being a mixture, I'm guessing you mean for it to be multiplied. Instead it just hangs at the end which throws issues for the function:
return(sum(log(dgamma(x, shape = param["k1"], scale = param["theta1"]) *
param["p1"] +
dgamma(x, shape = param["k2"], scale = param["theta2"]) *
(1 - param["p1"])))) ## ISSUE HERE: Is this what you meant?
There could be other issues with the code. I would double check that the function you are optimizing is what you think it ought to be. It's also hard to tell unless you give a reproducible example we might be able to use. Try to clear up the above issue and let us know if there are still problems.

R: How to use current function output's within this function

I write a R function using if & else if in it. See the code below:
i_ti_12 <- function(x){
if (x <= 44)
{ti = exp(-13.2238 + 0.152568*x)}
else if (x >= 49)
{ti = -0.01245109 + 0.000315605*x}
else (x > 44 & x < 49)
{ti = (x-44)*(i_ti_12(49))/(49-44) + (49-x)*(i_ti_12(44))/(49-44)}
return(ti)
}
I want to use this function's output, i_ti_12(49) within this function, but the above code doesn't work. The output is:
> i_ti_12(49)
Error: C stack usage 7974292 is too close to the limit
The simple solution is just replace i_ti_12(49) by -0.01245109 + 0.000315605*49, but its not a clear way to solve it and might not work in complex cases.
So I really want to know and to learn if there are clear methods to do this? I mean, like above simple example, write a conditional function using one condition's output in this function. Any help is highly appreciate.
Your last else is followed by a condition (x > 44 & x < 49), which actually is not correct. If you have (x > 44 & x < 49) there, that means you will execute that statement, and ti = (x-44)*(i_ti_12(49))/(49-44) + (49-x)*(i_ti_12(44))/(49-44) is something independent with your if-else structure.
In that case, when you call i_ti_12(49), your function does not know when the recursion should be terminated since you did not define that case.
You can try the code below:
i_ti_12 <- function(x){
if (x <= 44)
{ti = exp(-13.2238 + 0.152568*x)}
else if (x >= 49)
{ti = -0.01245109 + 0.000315605*x}
else
{ti = (x-44)*(i_ti_12(49))/(49-44) + (49-x)*(i_ti_12(44))/(49-44)}
return(ti)
}
such that
> i_ti_12(49)
[1] 0.003013555

Evaluating the output of a condition in R?

In the below R function, I was wondering how I could get R to evaluate whether the object input outputs n or es?
Note: I will need to know the exact output of input, so I canNOT be using identical() etc.
Here is what I have tried with no success:
d = function(n, es){
input = if(length(n) > 1) n else if(length(es) > 1) es else n
if(input == n) cat("yes") else cat("No") # IF `input` is `n` cat("yes") otherwise cat("no")
}
d(n = c(2, 3), es = 1)
try to use if(identical(n, input)) cat("yes") else cat("No"). == cannot be

Argument is of length zero in if statement using R

Does anyone know how I can solve this problem?
for (x in 1:nrow(homer1)-1) {if ((homer1$Start [x+1] +1) == homer1$End [x]) {homer1$annnot_prom <- paste(homer1$Detailed.Annotation, homer1$Nearest.PromoterID, sep="_") } else {homer1$annnot_prom <- homer1$Detailed.Annotation} }
Error in if ((homer1$Start[x + 1] + 1) == homer1$End[x]) { :
argument is of length zero
Add some brackets to your for loop:
for (x in 1:(nrow(homer1)-1))

Resources