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])
}
}
1 Answer 1
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.
-
\$\begingroup\$ 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! \$\endgroup\$user86777– user867772015年10月14日 13:10:58 +00:00Commented Oct 14, 2015 at 13:10
Explore related questions
See similar questions with these tags.