Rory
Rory

Reputation: 25

How would I write a function that takes a vector as input and evaluates its magnitude using a for loop in R?

I am trying to write a function that will take the vector c(10, -2, 4, 0, 2, -4, 2) and evaluate its magnitude and return 12... I am very new to R, thank you.

input = c(10, -2, 4, 0, 2, -4, 2)
evaluate <- function(input){
  for(i in input){
    sum = sum(input)
  } 
  print(sum)
}

Upvotes: 0

Views: 2801

Answers (1)

Len Greski
Len Greski

Reputation: 10865

The basic data structure in R is the vector. In fact, what one would normally call a scalar is implemented in R as a vector containing a single element.

Most R functions that work on numeric data work directly with vectors, and hence, no loops are required.

Therefore a function to calculate the sum of the elements in a vector would look like:

mySum <- function(x){
   sum(x)
}

That said, a custom function is unnecessary because one can simply use the sum() function to calculate the sum of the vector.

input <- c(10, -2, 4, 0, 2, -4, 2)
mySum <- sum(input)

Since vector processing in R is a capability that improves the speed of execution, it's very important for beginning R users to learn how to leverage this feature in one's code wherever possible.

A solution that sums a vector as asked in the question looks like this:

input <- c(10, -2, 4, 0, 2, -4, 2)
sumVector <- function(x){
  mySum <- 0  # initialize result value 
  for(i in x){
    mySum <- sum(mySum,i)
  } 
  mySum # return final value as result of function
}

Within the function, first we create a holding variable to store the intermediate calculations, mySum. Then, we loop through the elements in the input vector, adding each value to the intermediate variable. Finally, we return the result to the parent environment by printing the intermediate variable.

...and the output:

> sumVector(input)
[1] 12

However, a simple element-wise sum is not the magnitude of a vector...

Calculating magnitude of a vector at the origin

The magnitude of a vector is the distance of a point from the origin in a Cartesian coordinate system (for two or three dimensions), or more generally, an n-dimensional Euclidean space.

We can use Pythagorean Theorem, C = sqrt(A^2 + B^2), to calculate the magnitude for a two dimensional vector as follows.

magnitude <- function(x){
     sqrt(sum(x * x))
}

input <- c(-5,3)
magnitude(input)

...and the output:

> magnitude(input)
[1] 5.830952

The magnitude function as written above takes advantage of R vector processing. The code to calculate the squared values of each element in the vector x is rendered as x * x, which R interprets as "multiply each element of x by itself." This operation returns a vector that has the same number of elements as the original x vector.

We can illustrate this with the input vector from the original question.

> input * input
[1] 100   4  16   0   4  16   4

Therefore, the function handles vectors with more than 2 dimensions, as we illustrate with a 3 dimensional vector.

input <- c(2,3,5)
magnitude(input)

...and the output:

> magnitude(input)
[1] 6.164414

Returning to the original question, the magnitude of the vector provided in the question in this specific case happens to be equal to the sum of the individual values within the vector.

> input <- c(10, -2, 4, 0, 2, -4, 2)
> magnitude(input)
[1] 12 

Why? It turns out that for this vector, the sum of the squared values of the elements is 144, and after we take a square root to calculate the distance from the origin to the point in the 7-dimensional space, we get 12.

A for() based implementation of magnitude()

We can break down the vector processing with a for() loop as requested in the original question as follows.

magnitude <- function(x){
     sumOfSquares <- 0
     for(i in x) sumOfSquares <- sum(i^2,sumOfSquares)
     sqrt(sumOfSquares)
}

We can test the implementation by comparing it to results produced above.

input <- c(10, -2, 4, 0, 2, -4, 2)
magnitude(input)
input <- c(2,3,5)
magnitude(input)
input <- c(-5,3)
magnitude(input)

...and the output:

> input <- c(10, -2, 4, 0, 2, -4, 2)
> magnitude(input)
[1] 12
> input <- c(2,3,5)
> magnitude(input)
[1] 6.164414
> input <- c(-5,3)
> magnitude(input)
[1] 5.830952

Upvotes: 2

Related Questions