Why does repeating a loop change the results of looped optimization? - r

My original function embodies several optimize() functions, for which I get different results when I apply the function the first time vs. second time.
I tried this but I made sure that the returned value is one-dimensional.
fn = function(A,P){
l_fn = function(x) {
L <- x[1]
-((A*L*P)-(P*L^2)) # -1 because optimize-function finds minimum
}
l_opt <- as.numeric(optimize(l_fn,c(0,1000))[2]) # get objective output
return(l_opt)
}
f <- data.frame(x=c(10:20))
for (i in 1:length(f)) { # run this part 2 times!
f$test <- sin(f$x) # this is how I expect a function to behave
f$out[i] <- fn(f$x[i],100)
}
running the code the first time produces f$out that are all equal (weird). running the for loop again changes f$out, eventhough the input parameters remain the same! How is that possible?

Related

Running function in for-loop

New to R here and trying to place a function in a for loop. The function works and the for loop worked when I had another function in it, but when I put them together I am getting the error "missing value where TRUE/FALSE needed" when I didn't need one before. The function I have is :
roll <- function(){
die<- 1:20 # 20 sided die
dice <- sample(die, 2, replace=TRUE) # Roll the die twice
sum(dice) # Add results
}
and I am trying to get it to run 100+ times while putting the output in a matrix. Maybe I am just not quite grasping the problem with the for loop but I have it as such:
for(i in 1:nrolls) { #nrolls=100
roll <- sample(die)
if(roll[i] >= 25) {
G_than <- 1
} else{
L_than <- 1
}
}
Any help would be appreciated!
For loop aren't what you should use in that case.
Simply use sapply if you want to get the result in a vector like this:
roll <- function(x){
die<- 1:20 # 20 sided die
dice <- sample(die, 2, replace=TRUE) # Roll the die twice
sum(dice) # Add results
}
sapply(c(1:100), roll)
Note that sapply will send the argument to the function, so you need to change roll to get that input (and do nothing with it)

How to use lapply with a condition in R to fit only one element each time

Suppose I have two vectors. Suppose further that I would like my function takes only one values of each vector and return me the output. Then, I would like another function to check the values of each run. If the output of the previous run is smaller than the new one. Then, I would like my function to stop and return me all the previous values. My original function is very complicated (estimation models). Hence, I try to provide an example to explain my idea.
Suppose that I have these two vectors:
set.seed(123)
x <- rnorm(1:20)
y <- rnorm(1:20)
Then, I would like to write a function which only takes one values of each vector and multiplied them. Then, return me the output. Then, I would like the function to check if the previous multiplication is smaller than the new one or not. If yes, then stop and return me all the previous multiplication.
I tried this:However, this functions takes all the values at once and return me a list of the multiplication. I was thinking about using lapply, to fit one element at a time but I do not know how to work with the conditions.
myfun <- function(x, y, n){
multi <- list()
for ( i in 1:n){
multi[[i]] <- x[[i]]*y[[i]]
}
return(multi)
}
myfun(x,y,10)
Here is another try
x <- rnorm(1:20)
y <- rnorm(1:20)
myfun <- function(x, y){
multi <- x*y
return(multi)
}
This is the first function. I would like to run it element by element. Each time, I would like it to returns me only one multiplication result. Then, another function (wrapper function) check the result. It the second output of the first function (multiplication function) is larger than the first one, then stop, otherwise keep going.
I would like to write a function which only takes one values of each vector and multiplied them. Then, return me the output. Then, I would like the function to check if the previous multiplication is smaller than the new one or not.
I would like the multiplication in a separate function. Then, I would like to check its output. So, I should have a warper function.
You can apply a for loop with a stopping condition, similar to what you have already:
# example input
set.seed(123)
x <- rnorm(1:20)
y <- rnorm(1:20)
# example function
f = function(xi, yi) xi*yi
# wrapper
stopifnot(length(x) == length(y))
res = vector(length(x), mode="list")
for (i in seq_along(x)){
res[[i]] = f(x[[i]], y[[i]])
if (i > 1L && res[[i]] > res[[i-1L]]) break
}
res[seq_len(i)]
Comments:
It is better to predefine the max length res might need (here, length(x)), rather than expanding it in the loop.
For this function (multiplication), there is no good reason to proceed elementwise. R's multiplication function is vectorized and fast.
You don't need to use a list-class output for this function, since it is returning doubles; res = double(length(x)) should also work.
You don't need to use list-style accessors for x, y and res unless lists are involved; res[i] = f(x[i], y[i]) should work, etc.

How to take results of a function and apply it to function again in R?

I am aware this is a very basic question and am sorry to take up everyone's time. I created a function but would like to take those results, and apply it to the function again ( I am trying to model growth).
I don't think I want to use a loop because I need the values to come from the function. I also don't think it's apply because I need to extract the values from the function.
Here is my function
initial<-c(36.49)
second<-NULL
growth <- function(x){
second <- (131.35-(131.35 -x)*exp(-0.087))
}
second<-growth(initial)
third<-growth(second)
fourth<-growth(third)
fifth<-growth(fourth)
sixth<-growth(fifth)
seventh<-growth(sixth)
here is how I am doing it now, but as you can see I would have to keep doing this over and over again
You can use loop. Just store the outputs in a vector:
# initial value
initial<-c(36.49)
# dont need this i think
# second<-NULL
# create a holding vector fro result
values <- vector()
# assign
values[1] <- initial
# your function
growth <- function(x){
second <- (131.35-(131.35 -x)*exp(-0.087))
}
# start a loop; you start with 2
for(i in 2:7){
# then access the previous value using i - 1
# then store to the next index, which is i
values[i] <- growth(values[i - 1])
}
This should do the same.
Something along the lines of this maybe can help
x <- 1
try <- function(x) x <<- x+1
for(i in 1:5) try(x)

How does lazy evaluation binds variable (in R)

I'm fairly new to R and I just noticed that the first call to a function seems to bind its environment parameters. How does this work ? (Or how is it it called, so I can look it up in the doc).
E.g.:
make.power <- function(n)
{
pow <- function(x)
{
x^n
}
}
i <- 3
cube <- make.power(i)
# print(cube(3)) # uncommenting this line change the value below
i <- 2
square <- make.power(i)
print(cube(3)) # this value changes depending on whether cube(3) was called before.
print(square(3))
I'm looking for a sample explanation of what's going on, or just the name of this feature, so I can look it up.
Thanks !

R Shiny: For loop only saves 1 iteration in list

everyone.
I am programming a simulation app in Shiny R and I am stuck at the for loops.
Basically, in an reactive I am calling a function that loops through a couple of other functions, like this:
In the server.R:
output.addiction <- reactive ({
SimulateMultiple(input$no.simulations, vectors(), parameters(), input$S.plus, input$q,
input$weeks, input$d, list.output)
})
The function:
SimulateMultiple <- function (no.simulations, vectors, parameters, S.plus, q, weeks, d, list.output) {
for (i in 1:no.simulations) {
thisi <- i
simulation <- SimulateAddictionComponents(vectors, parameters, S.plus, q, weeks, d) # returns list "simulation"
df.output <- BuildOutputDataframe(weeks, simulation, vectors) # returns "df.outout"
output.addiction <-BuildOutputList(df.output, simulation, list.output) # returns "output.addiction"
}
return(output.addiction)
}
And, again, the last function that creates the out put list:
BuildOutputList <- function (df.output, simulation, list.output) {
addiction <- simulation$addiction
output.w.success <- list(df.output, addiction) # includes success data
output.addition <- c(list.output, list(output.w.success)) # adds the new data to the list
return(output.addition)
}
I read about the issue online a lot, I tried to isolate some stuff, to introduce a local({}) etc. But it never works. In the end, I get a list of length 1.
I would be forever grateful, if you could help me - I have been on this for two days now.
The problem solved itself when I edited the code in the function from
output.addition <- c(list.output, list(output.w.success)) # adds the new data to the list
return(output.addition)
to
list.output <- c(list.output, list(output.w.success)) # adds the new data to the list
return(list.output)
so as to not overwrite the object every time in the loop. After all - very easy and stupid problem, but hard to spot.

Resources