why is my R function not printing values? - r

s <- seq(-10, 6, by = 0.1)
my.fun = function(s)
{
n = length(s)
s = 0
for(i in 1:n)
{
s = ((s[i]*s[i]*s[i]*s[i])*sin(1/s[i]) +(s[i]*s[i]))/(1+abs((s[i]*s[i]*s[i])))
}
s
}
This is my function. I am attempting to compute a sequence of numbers and then use that sequence within the equation. However, It isnt saving the new variable S and the function wont print anything out either.

Two reasons:
You're setting s to zero in your function
The main guts of your function contains 1/s[i], so s shouldn't contain any zeroes.
Try
s <- seq(-10, 6, by = 0.1)
s = s[which(s != 0)] # to drop the zero from the vector
my.fun = function(s)
{
n = length(s)
for(i in 1:n) {
s[i] = ((s[i]*s[i]*s[i]*s[i])*sin(1/s[i]) + s[i]*s[i]))/(1+abs((s[i]*s[i]*s[i])))
}
s
}
my.fun(s)

You cant return an output in the definition of a function itself.
Do my.fun(s) to return the output for s.
Also make sure to not have 0s while initializing values for s. Since you are doing 1/s at one point, you will return only NaNs.

Related

Writing a Function with a list from a stored Calculation

I'm trying to write a function for CLV that stores the values for each year, indexed 0 to t, in a list and sums the list. What I have:
CLV_simple <- function (r, t, M, Alpha){
CLV = list()
for (i in 0:t){
CLV[i] <- M*(Alpha/(1+r))^i
return(sum(CLV))
}
}
CLV_simple(.10, 4, M, Alpha)
where CLV[0] = M*(Alpha/(1+r))^0,
CLV[1] = M*(Alpha/(1+r))^1, so on to CLV[4].
Alpha and M are defined as variables earlier. Assume Alpha is .81 and M is 40.23
the return should be the sum of each year or:
(M*(Alpha/(1+.10))^0) + (M*(Alpha/(1+.10))^1) + (M*(Alpha/(1+.10))^2) + (M*(Alpha/(1+.10))^3) + (M*(Alpha/(1+.10))^4)
[1] 121.4646
When I run my function all I get is this:
CLV_simple(.10, 4, M, Alpha)
list()
so something isn't being saved to the list right and I'm not sure why.
In your code,
return makes your code jump out of for loop after the first iteration. You should move return to the end of your function body where for loops are done.
Also, i is an index to access CLV, which should starts from 1 instead of 0 from 0:t.
One more thing, CLV should be initialized as c(), since elements in list() cannot summed up directly.
You can try for loop like below
CLV_simple <- function (r, t, M, Alpha){
CLV <- c()
for (i in 0:t){
CLV[i+1] <- M*(Alpha/(1+r))^i
}
return(sum(CLV))
}
or a simpler one
CLV_simple2 <- function(r,t,M,Alpha) sum(M*(Alpha/(1+r))^(0:t))

How to create matrix of all 2^n binary sequences of length n using recursion in R?

I know I can use expand.grid for this, but I am trying to learn actual programming. My goal is to take what I have below and use a recursion to get all 2^n binary sequences of length n.
I can do this for n = 1, but I don't understand how I would use the same function in a recursive way to get the answer for higher dimensions.
Here is for n = 1:
binseq <- function(n){
binmat <- matrix(nrow = 2^n, ncol = n)
r <- 0 #row counter
for (i in 0:1) {
r <- r + 1
binmat[r,] <- i
}
return(binmat)
}
I know I have to use probably a cbind in the return statement. My intuition says the return statement should be something like cbind(binseq(n-1), binseq(n)). But, honestly, I'm completely lost at this point.
The desired output should basically recursively produce this for n = 3:
binmat <- matrix(nrow = 8, ncol = 3)
r <- 0 # current row of binmat
for (i in 0:1) {
for (j in 0:1) {
for (k in 0:1) {
r <- r + 1
binmat[r,] <- c(i, j, k)}
}
}
binmat
It should just be a matrix as binmat is being filled recursively.
I quickly wrote this function to generate all N^K permutations of length K for given N characters. Hope it will be useful.
gen_perm <- function(str=c(""), lst=5, levels = c("0", "1", "2")){
if (nchar(str) == lst){
cat(str, "\n")
return(invisible(NULL))
}
for (i in levels){
gen_perm(str = paste0(str,i), lst=lst, levels=levels)
}
}
# sample call
gen_perm(lst = 3, levels = c("x", "T", "a"))
I will return to your problem when I get more time.
UPDATE
I modified the code above to work for your problem. Note that the matrix being populated lives in the global environment. The function also uses the tmp variable to pass rows to the global environment. This was the easiest way for me to solve the problem. Perhaps, there are other ways.
levels <- c(0,1)
nc <- 3
m <- matrix(numeric(0), ncol = nc)
gen_perm <- function(row=numeric(), lst=nc, levels = levels){
if (length(row) == lst){
assign("tmp", row, .GlobalEnv)
with(.GlobalEnv, {m <- rbind(m, tmp); rownames(m) <- NULL})
return(invisible(NULL))
}
for (i in levels){
gen_perm(row=c(row,i), lst=lst, levels=levels)
}
}
gen_perm(lst=nc, levels=levels)
UPDATE 2
To get the expected output you provided, run
m <- matrix(numeric(0), ncol = 3)
gen_perm(lst = 3, levels = c(0,1))
m
levels specifies a range of values to generate (binary in our case) to generate permutations, m is an empty matrix to fill up, gen_perm generates rows and adds them to the matrix m, lst is a length of the permutation (matches the number of columns in the matrix).

adding elements to a vector in R

I'm trying to create a function that simulate dolling m dice, n times, calculate the minimum of the outcome of the dice in each roll and then calculate the mean of the minimum and store the values into a vector.
mindice = function(n = 10, m = 3)
{
v <- vector
for(i in 1:10)
{
minima= numeric(n)
for(i in 1:n)
{
minima[i] = min(sample(6,m,replace=T))
}
v[i] = mean(minima)
}
v
}
I'm calling the function like that: mindice()
and the output is: Error in v[i] <- mean(minima) : object of type 'closure' is not subsettable
any help will be appreciated
I don't know if this fits your expectations. This function returns both the vector for the minimum per roll and their average
mindice <- function(n = 10, m = 3)
{
minima <- vector("numeric")
for(i in 1:n){
minima = c(minima, min(sample(6,m,replace=T)))
}
list(minimum_values=minima,
mean_minima=mean(minima))
}
mindice()
The comment about using v = vector() rather than v = vector should solve the bug in the way you've written the function. If you're interested in a more R-like way to do this function, try this:
mindice2 = function(n = 10, m = 3) {
rolls = sample(6, size = m * n, replace = TRUE)
rolls = matrix(rolls, nrow = m)
minima = apply(rolls, MARGIN = 2, FUN = min)
cum_mean = cumsum(minima) / seq_along(minima)
return(cum_mean)
}
Rather than sampling each roll separately, we do all the rolls at once (more efficient), and then put them in a matrix where each column is a roll of m dice. We can then use apply to find the minima, and cumsum to calculate the mean minimum after each roll.

subscript out of bounds error with two for loops inside the function

I am trying to use a two dimension matrix to produce a two dimension matrix result where
the number of rows and number of columns are determined in a new way everytime I change the values in the function which determines the number of rows and number of columns accordingly.
The function that I would like to ask and resolve the "subscript out of bounds" problem is the following:
HRC <- function(n,b,c)
{
R=matrix( ,nrow = n*b, ncol = c)
R[0,]=133
for (j in 1:c)
{
r=rnorm(n*b)
for (i in 1:n*b){
R[i+1,j]=R[i,j]+3*b/r[i]
}
}
return(R)
}
HRC(10,1,3)
The error message that I get is the following:
Error in R[i + 1, j] = R[i, j] + 3 * b/r[i] : subscript out of bounds
I wonder how I can resolve this problem. Thank you so much in advance.
R's indexing starts at 1, not 0.
You also have to be careful with the operators precedence rules: the : operator has higher precedence than *. See ?Syntax.
This should work:
HRC <- function(n, b, c) {
R <- matrix(NA, nrow = n*b, ncol = c)
R[1,]=133
for (j in 1:c) {
r = rnorm(n*b)
for (i in 1:(n*b-1)){
R[i+1,j] = R[i,j] + 3*b/r[i]
}
}
return(R)
}
HRC(10,1,3)
The problem is that you loop from row b to row n*b (with stride b, due to the precedence of * and :) and then index to one greater, so you attempt to index row n*b + 1 of R, which is out of bounds.
R[0,]<- will cause incorrect results but not elicit an error from R.
I find the code easier to read if you loop from 2 to n*b, the number of rows, and write the formula in terms of creating row i from row i-1 (rather than creating row i+1 from row i).
In addition, you can drop one loop dimension by vectorizing the operations over the rows:
HRC <- function(n, b, c) {
R <- matrix(NA, nrow = n*b, ncol = c)
R[1,] <- 133
r <- matrix(rnorm(n*b*c), ncol=c)
for (i in 2:(n*b)){
R[i,] <- R[i-1,] + 3*b/r[i-1,]
}
return(R)
}
HRC(10,1,3)
Here, the same number of random samples are taken with rnorm but they are formed as a matrix, and used in the same order as used in the question. Note that not all of the random values are actually used in the computation.
If you set a random seed and then run this function, and the function in #flodel's answer, you will get identical results. His answer is also correct.
I think you are making three mistakes:
First: You are messing up the row count on the index. It should be 1:(n*b) and not 1:n*b.
Second: In R, indexing starts at 1. So R[0,] should be replaced by R[1,].
Third: You are running the loops in the right bounds 1:c and 1:(n:b), but you are probably not keeping track of the indices.
Try this:
set.seed(100)
HRC <- function(n, b, c) {
R <- matrix(0, nrow = n*b, ncol = c)
R[1,] <- 133
for (j in 1:c) {
r <- rnorm(n*b)
for (i in 2:(n*b)){
R[i,j] <- R[i-1,j] + 3*b/r[i-1]
}
}
return(R)
}
HRC(10,1,3)
Lastly, I would like to warn you about interchangeable use of the assignment operators. See here.

Simulation Study Calling Function

I spend multiple hours of thinking about the following problem. I am running a simulation study and I want to define functions outside the simulation study in order to be able to call these functions in the end of my code.
This example illustrates the problem, but is not replicable (below you will find a replicable example of the problem). I make use of the "metafor" package for doing a meta-analysis.
I would like to use the following function that I define outside my final simulation code:
mat <- matrix(NA, nrow = 8, ncol = 3)
funtr.stu <- function(i) {
for (y in 1:8) {
mat[y,i] <- tr[[y]]$k0
}
return(mat)
}
"tr" is a list and consists of the results of 8 times an analysis. I want to retrieve the object "k0" from that list and store it into the matrix "mat".
In the following part of the code (in which I run the simulation), I want to call the function and fill the matrix "mat" with the correct numbers.
for (i in 1:iterations) {
tr.stu <- funtr.stu()
}
The result of this code is a filled matrix, but within each column the same numbers. Thus, R isnĀ“t storing the numbers every iteration, but stores only the last iteration.
How can I modify my code in such a way that R is storing the output as I want?
A very simplified example:
Mat represents just a matrix with numbers and res is an empty matrix that I want to fill.
mat <- matrix(data = c(1,2,3,4,5,6), ncol = 2, nrow = 3)
res <- matrix(NA, ncol = 2, nrow = 3)
I use the function "fun" to fill the empty matrix res.
fun <- function() {
for (i in 1:2) {
res[y,i] <- mat[y,i]
}
return(res)
}
This is what I would like to put in the end of my code (I just want to call the function and with this function I want to fill the matrix "res"). However, if I use the code below R only fills the third row and not the first and second row.
for (y in 1:3) {
test <- fun()
}
Thank you in advance!
This should work in your case. Basically, return one row in each iteration of the for loop. Where as you are returning the entire 'res' matrix.
mat <- matrix(data = c(1,2,3,4,5,6), ncol = 2, nrow = 3)
res <- matrix(NA, ncol = 2, nrow = 3)
fun <- function() {
for (i in 1:2) {
res[y,i] <- mat[y,i]
}
return(res[y,])
}
for (y in 1:3) {
test[y,] <- fun()
}

Resources