abs27
abs27

Reputation: 39

how to create a new vector via loop

a) Create a vector X of length 20, with the kth element in X = 2k, for k=1…20. Print out the values of X.

b) Create a vector Y of length 20, with all elements in Y equal to 0. Print out the values of Y.

c) Using a for loop, reassigns the value of the k-th element in Y, for k = 1…20. When k < 12, the kth element of Y is reassigned as the cosine of k. When the k ≥ 12, the kth element of Y is reassigned as the value of integral sqrt(t)dt from 0 to K.

for the first two questions, it is simple.

 > x1 <- seq(1,20,by=2) 
 > x <- 2 * x1 
 > x
  [1]  2  4  6  8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40
 > y <- rep(0,20)
 > y
  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  

i got stuck on the last one,

 t <- function(i) sqrt(i)
 for (i in 1:20) {
   if (i < 12) {
  y[i] <- cos(i)
  }
   else if (i >= 12) {
   y[i] <- integral(t, lower= 0, Upper = 20)
  }
  }
  y // print new y 

Any suggestions? thanks.

Upvotes: 0

Views: 2582

Answers (2)

Avraham
Avraham

Reputation: 1719

What may help is that the command to calculate a one-dimensional integral is integrate not integral.

You have successfully completed the first two, so I'll demonstrate a different way of getting those vectors:

x <- 2 * seq_len(20)
y <- double(length = 20)

As for your function, you have the right idea, but you need to clean up your syntax a bit. For example, you may need to double-check your braces (using a set style like Hadley Wickham's will help you prevent syntax errors and make the code more readable), you don't need the "if" in the else, you need to read up on integrate and see what its inputs, and importantly its outputs are (and which of them you need and how to extract it), and lastly, you need to return a value from your function. Hopefully, that's enough to help you work it out on your own. Good Luck!

Update

Slightly different function to demonstrate coding style and some best practices with loops

Given a working answer has been posted, this is what I did when looking at your question. I think it is worth posting, as as I think that it is a good habit to 1) pre-allocate answers 2) prevent confusion about scope by not re-using the input variable name as an output and 3) use the seq_len and seq_along constructions for for loops, per R Inferno(pdf) which is required reading, in my opinion:

tf <- function(y){
  z <- double(length = length(y))
  for (k in seq_along(y)) {
    if (k < 12) {
      z[k] <- cos(k)
    } else {
      z[k] <- integrate(f = sqrt, lower = 0, upper = k)$value
    }
  }
  return(z)
}

Which returns:

> tf(y)
 [1]  0.540302306 -0.416146837 -0.989992497 -0.653643621  0.283662185  0.960170287  0.753902254 
 [8] -0.145500034 -0.911130262 -0.839071529  0.004425698 27.712816032 31.248114562 34.922139530
[15] 38.729837810 42.666671456 46.728535669 50.911693960 55.212726149 59.628486093

Upvotes: 2

LyzandeR
LyzandeR

Reputation: 37879

To be honest you almost have it ready and it is good that you have showed some code here:

y <- rep(0,20) #y vector from question 2

for ( k in 1:20) {              #start the loop
  if (k < 12) {                 #if k less than 12
    y[k] <- cos(k)              #calculate cosine
  } else if( k >= 12) {         #else if k greater or equal to 12
    y[k] <- integrate( sqrt, lower=0, upper=k)$value #see below for explanation
}
}
print(y) #prints y

> print(y)
 [1]  0.540302306 -0.416146837 -0.989992497 -0.653643621  0.283662185  0.960170287  0.753902254 -0.145500034 -0.911130262 -0.839071529  0.004425698
[12] 27.712816032 31.248114562 34.922139530 38.729837810 42.666671456 46.728535669 50.911693960 55.212726149 59.628486093

First of all stats::integrate is the function you need to calculate the integral

 integrate( sqrt, lower=0, upper=2)$value

The first argument is a function which in your case is sqrt. sqrt is defined already in R so there is no need to define it yourself explicitly as t <- function(i) sqrt(i)

The other two arguments as you correctly set in your code are lower and upper.

The function integrate( sqrt, lower=0, upper=2) will return:

1.885618 with absolute error < 0.00022

and that is why you need integrate( sqrt, lower=0, upper=2)$value to only extract the value.

Type ?integrate in your console to see the documentation which will help you a lot I think.

Upvotes: 1

Related Questions