Converting polar coordinates to Cartesian coordinates

I have a functional script that converts polar coordinates to Cartesian coordinates and then matches a value in a separate array to the coordinates. It works well, but I find that it takes a long time to run due to the length of the matrices being processed. Each file has four columns and 2,880,000 rows which means that I have 11,520,000 total values being processed. The data looks like this-

[,1] [,2] [,3]
[1,]    1    1    1
[2,]    2    2    2
[3,]    3    3    3

The array rf.190301 is a three dimensional array that looks like this-

, , 1

[,1] [,2] [,3]
[1,]    1    1    1
[2,]    2    2    2
[3,]    3    3    3

, , 2

[,1] [,2] [,3]
[1,]    1    1    1
[2,]    2    2    2
[3,]    3    3    3

, , 3

[,1] [,2] [,3]
[1,]    1    1    1
[2,]    2    2    2
[3,]    3    3    3

I'm fairly new to R and am just looking for a way to optimize what I'm trying to do in order to make it run a bit faster.

Polar2Cart <- function(x) {

Cart.x <- matrix(NA, nrow = 2880000, ncol = 4)

for (i in 1:nrow(x)) {

z[i]<- x[i,1]
t[i]<- x[i,2]
r[i]<- x[i,3]

theta.polar[i] <- (x[i,2] * (pi/180))
r.polar[i] <- (x[i,3] * 0.075)

x.cart[i] <- r.polar[i]*cos(theta.polar[i])
y.cart[i] <- r.polar[i]*sin(theta.polar[i])
value[i] <- rf.190301[z[i], t[i], r[i]]

Cart.x[i,] <- cbind(z[i], y.cart[i], x.cart[i], value[i])
}
}

You are missing a key feature of the R language: "vectorization". A fancy word for saying that most functions are implemented in such a way that you can provide them vectors and they will apply the computations to each element. As an example, the multiplication function * is vectorized so you can do r.polar <- x[, 3] * 0.075 and it will return the full vector of x[i, 3] * 0.075 where i goes from 1 to nrow(x). This is less typing than doing for (i in 1:nrow(x)) { r.polar[i] <- (x[i,3] * 0.075) } and also a lot faster as you can test.

Applying that idea throughout your code, you can rewrite your Polar2Cart as follows:

Polar2Cart <- function(x) {
z <- x[, 1]
t <- x[, 2]
r <- x[, 3]
theta.polar <- t * pi / 180
r.polar <-  r * 0.075
x.cart <- r.polar * cos(theta.polar)
y.cart <- r.polar * sin(theta.polar)
value  <- rf.190301[cbind(z, t, r)]
Cart.x <- cbind(z, y.cart, x.cart, value)
}

One thing that needs explanation is the use of rf.190301[cbind(z, t, r)]. It is a little known use of the [ function documented as follows (you can access the doc by typing ?"[")

A third form of indexing is via a numeric matrix with one column for each dimension: each row of the index matrix then selects a single element of the array, and the result is a vector.

Finally, a recommendation. Be careful using single characters as variable names, since R already uses a few of them for built-in variables or functions. You could for example confuse your variable t for the t() function for transposing data. Other single character variable names used by R that come to mind are c (concatenation), q (quit), T (TRUE), F (FALSE), I (inhibit). Anyway, it is always better to use descriptive variable names and that usually implies more than one character.

• Thank you so much for this! I took an R class a couple years ago, but I haven't used it much since. I really appreciate your knowledge and the great way that you convey it! Thanks again! – user86777 Oct 14 '15 at 13:10