Reputation: 6179
This question is related to another question which I asked here.
My data frame contains velocities and accelerations of vehicles in every 0.1 seconds time frames. Following shows very few data points of the data frame which originally contains more than 1,000,000 rows:
> dput(head(traj2[, c(1,2,12,13)], 30))
structure(list(Vehicle.ID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L), Frame.ID = 270:299, Vehicle.velocity = c(19.89,
19.89, 19.89, 19.89, 19.89, 19.97, 20, 19.86, 19.18, 18.17, 17.63,
17.87, 18.76, 19.67, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 19.99, 19.98), Vehicle.acceleration = c(0, 0,
0, 0, 1.07, 0.6, 0, -2.42, -9.79, -11.2, -2.64, 9.2, 11.2, 5.32,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.11, -0.2)), .Names = c("Vehicle.ID",
"Frame.ID", "Vehicle.velocity", "Vehicle.acceleration"), row.names = c(NA,
30L), class = "data.frame")
Please note that there are about 2000 unique Vehicle.ID
s, each repeating in different number of frames.
I want to smooth the velocities and accelerations by using the equation provided in the first question. But I want to minimize the time and make the code as efficient as possible.
I used following code for smoothing:
# VELOCITY SMOOTHING FUNCTION
smooth <- function (x, D, delta){
z <- exp(-abs(-D:D/delta))
r <- convolve (x, z, type='filter')/convolve(rep(1, length(x)),z,type='filter')
r
}
# ACCELERATION SMOOTHING FUNCTION
smootha <- function (x, D, delta){
za <- exp(-abs(-D:D/delta))
ra <- convolve (x, za, type='filter')/convolve(rep(1, length(x)),za,type='filter')
ra
} ### D=3*delta = 3*40 = 120, delta for acceleration = T / dt = 4 seconds/0.1 = 40
ftaa <- list()
# Split data by vehicle ID
length(ftaa) <- length(unique(traj1$'Vehicle.ID'))
# Apply smoothing function
for (i in 1:length(unique(traj2$'Vehicle.ID'))){
veh <- subset (traj2, traj2$'Vehicle.ID'==unique(traj2$'Vehicle.ID')[i])
svel <- round(smooth(veh$'Vehicle.velocity',30,10), digits=2)
svel <- data.frame(svel)
svel <- head(tail(svel,-90),-90)
sacc <- round(smootha(veh$'Vehicle.acceleration',120,40), digits=2)
sacc <- data.frame(sacc)
veh <- head(tail(veh, -120), -120)
ftaa[[i]] <- cbind(veh,svel,sacc)
}
# Combining results
final.data1<-do.call("rbind", ftaa)
This approach takes about 40 minutes to complete smoothing the given data frame. Is there any way I could reduce this time?
Upvotes: 0
Views: 1683
Reputation: 4615
I highly recommend ditching the loop and using data.table
. Also, why not use the round
function inside of your smooth
and smootha
functions?
require(data.table)
setDT(traj2)
traj2[ , svel := smooth(Vehicle.velocity,30,10), by =Vehicle.ID]
traj2[ , sacc := smootha(Vehicle.acceleration,120,40), by =Vehicle.ID]
This is difficult to test because your problem is not setup in a reproducible way. Your smoothing functions need identically sized vectors (your link shows using convolve with type="open"
instead of how you are using it). But this is a good template for getting your code to run much much faster.
Upvotes: 2