-1

I have a simple function se <- 0.11 * (x^2) - 0.002 * x. I want to generate two output variables se.m and se.st- each storing the results from 100 iterations with randomly renerated values for x at specific intervals:

se.m <- 0.11 * (x^2) - 0.002 * x      # if x[0,1]

or

se.st <- 0.11 * (x^2) - 0.002 * x     # if x(1,5]

I have written this code:

my.mat <- matrix(0,100,2)
x <- runif(n = 1, min = 0, max = 5)

fuchs <- function(n){
   x.m <- runif(n = 1, min = 0, max = 1)
   x.st <- runif(n = 1, min = 1, max = 5)
  for(i in 1:n){
    print(x.m[i] <- runif(n = 1, min = 0, max = 1))
    se.m <- 0.11 * (x.m^2) - 0.002 * x.m
    print(x.st[i] <- runif(n = 1, min = 1, max = 5))
    se.st <- 0.11 * (x.st^2) - 0.002 * x.st
    }
  return(list(se.m, se.st))
}
fuchs(100)

How can I store the output in two columns? I have tried using the matrix command, but i get an error that the data is too long:

my.mat<-matrix(my.mat, se.m) Error in matrix(my.mat, se.m) : data is too long

Also the list command doesnt yield any output.

I am new to R as you can guess and would very much appriciate constructive comments/critique.

Nneka
  • 1,764
  • 2
  • 15
  • 39
  • Another answer for your second question is simply: `cbind(se.m, se.st)` inside the function `fuchs()`. – nadizan Mar 14 '17 at 12:37

2 Answers2

1

I don't understand why you loop. All functions you use are vectorized.

x.m <- runif(100, 0, 1)

#ensure 1 is not included
repeat {
  x.st <- runif(100, 1, 5)
  if (!any((x.st - 1) < .Machine$double.eps)) break
}

cbind(0.11 * (x.m^2) - 0.002 * x.m,
      0.11 * (x.st^2) - 0.002 * x.st)

The most difficult problem is sampling from an half-open interval. That leads to considerations of floating point imprecision. As a result you'd need to exclude a fuzzy range around the interval limit. However, the probability that the lower interval limit is sampled is so low that it is practically zero. Thus, I wouldn't bother treating this case.

Community
  • 1
  • 1
Roland
  • 127,288
  • 10
  • 191
  • 288
0

1) The problem seems to be in indexing.

fuchs <- function(n){
x.m=se.m=x.st=se.st=NULL
  for(i in 1:n){
    print(x.m[i] <- runif(n = 1, min = 0, max = 1))
    se.m[i] <- 0.11 * (x.m[i]^2) - 0.002 * x.m[i]
    print(x.st[i] <- runif(n = 1, min = 1, max = 5))
    se.st[i] <- 0.11 * (x.st[i]^2) - 0.002 * x.st[i]
    }
  return(list(se.m, se.st))
}
fuchs(100)

In your original code, you set a single random numbers to variables x.m and x.st and then add additional values in the for cycle. In the last iteration, the equations work on the whole vector. Note that the se.m and se.st equations are identical:

se.m <- 0.11 * (x^2) - 0.002 * x
se.st <- 0.11 * (x^2) - 0.002 * x

2) To output the result in a matrix, use code provided in comments by jogo, or use a data.frame. To better troubleshoot the code, I suggest returning also respective x values.

return(data.frame(x.m = x.m, se.m = se.m, x.st = x.st, se.st = se.st))

3) The runif function generates a number from the uniform distribution without the extreme values in your case. Text from the function help:

runif will not generate either of the extreme values unless max = min or max-min is small compared to min, and in particular not for the default arguments.

nya
  • 2,138
  • 15
  • 29