The ConvertToLocal
function below takes a data frame of Names
and Times
and does a timezone conversion with some if statements. How can I vectorize this so I do not use loops?
Thank you.
Here is the code:
ConvertToLocal<-function(data)
{
Name<-data$Name
Time<-data$Time
for(i in 1:length(Name))
{
if(Name[i]== "Bob" | Name[i] == "Al" )
{
Time[i]<-format(Time[i],tz="America/Los_Angeles")
}else if (Name[i] == "Mike" | Name[i] == "Tom" )
{
Time[i]<-format(Time[i],tz="Asia/Singapore")
}else if (Name[i] == "Fred")
{
Time[i]<- format(Time[i],tz="Europe/London")
}
}
return(Time)
}
Time<-c(as.POSIXct("2015-02-03 14:27:35.943", tz = "UTC"),as.POSIXct("2015-02-03 14:27:35.943", tz = "UTC"),as.POSIXct("2015-02-03 14:27:35.943", tz = "UTC"),as.POSIXct("2015-02-03 14:27:35.943", tz = "UTC"))
Name<-c("BOB","Al","Mike","Fred")
data<- data.frame(Name = Name, Time = Time)
ConvertToLocal(data)
Loop vectorization transforms procedural loops by assigning a processing unit to each pair of operands. Programs spend most of their time within such loops. Therefore, vectorization can significantly accelerate them, especially over large data sets.
Vectorization is the process of converting an algorithm from operating on a single value at a time to operating on a set of values (vector) at one time. Modern CPUs provide direct support for vector operations where a single instruction is applied to multiple data (SIMD).
There are two ways to vectorize a loop computation in a C/C++ program. Programmers can use intrinsics inside the C/C++ source code to tell compilers to generate specific SIMD instructions so as to vectorize the loop computation. Or, compilers may be setup to vectorize the loop computation automatically.
What is Vectorization ? Vectorization is used to speed up the Python code without using loop. Using such a function can help in minimizing the running time of code efficiently.
Another approach would be to create a lookup table and then use mapply
Using data.table for ease of merging
library(data.table)
DT <- data.table(data)
TimeZones <-rbindlist(list(
data.table(Name = c('Bob', 'Al'), tz = 'America/Los_Angeles' ),
data.table(Name = c('Mike', 'Tom'), tz = 'Asia/Singapore'),
data.table(Name = 'Fred', tz = 'Europe/London')
))
setkey(DT, Name)
setkey(TimeZones, Name)
final <- TimeZones[DT][, local := mapply(Time, tz = tz, FUN = format)]
final
# Name tz Time local
# 1: Al America/Los_Angeles 2015-02-04 01:27:35 2015-02-03 06:27:35
# 2: Bob America/Los_Angeles 2015-02-04 01:27:35 2015-02-03 06:27:35
# 3: Fred Europe/London 2015-02-04 01:27:35 2015-02-03 14:27:35
# 4: Mike Asia/Singapore 2015-02-04 01:27:35 2015-02-03 22:27:35
You can easily do the 3 transformations as 3 separate vectorised steps.
Time <- c(as.POSIXct("2015-02-03 14:27:35.943", tz = "UTC"),
as.POSIXct("2015-02-03 14:27:35.943", tz = "UTC"),
as.POSIXct("2015-02-03 14:27:35.943", tz = "UTC"),
as.POSIXct("2015-02-03 14:27:35.943", tz = "UTC"))
Name <- c("BOB","Al","Mike","Fred")
data <- data.frame(Name = Name, Time = Time)
ConvertToLocal <- function(dat) {
tzs <- c("America/Los_Angeles", "Asia/Singapore", "Europe/London")
groups <- list(c("Bob", "Al"), c("Mike", "Tom"), c("Fred"))
for (i in seq_along(groups)) {
take <- dat$Name %in% groups[[i]]
dat$Time[take] <- format(dat$Time[take], tz = tzs[i], usetz = TRUE)
}
dat
}
which gives, for the example data
> ConvertToLocal(data)
Name Time
1 BOB 2015-02-03 08:27:35.943
2 Al 2015-02-03 06:27:35.943
3 Mike 2015-02-03 22:27:35.943
4 Fred 2015-02-03 14:27:35.943
try this:
ConvertToLocal<-function(data) {
Name<-data$Name
Time<-data$Time
indx <- Name== "Bob" | Name == "Al"
Time[indx]<-format(Time[indx],tz="America/Los_Angeles")
indx <- Name == "Mike" | Name == "Tom"
Time[indx]<-format(Time[indx],tz="Asia/Singapore")
indx <- Name == "Fred"
Time[indx]<- format(Time[indx],tz="Europe/London")
return(Time)
}
Here another option , using mapply
and ifelse
:
Name <- data$Name
Time <- data$Time
mapply(function(x,y)format(x,tz=y),Time,
ifelse(Name %in% c("Bob","Al" ),
"America/Los_Angeles",
ifelse(Name %in% c("Mike","Tom" ),
"Asia/Singapore",
ifelse(Name == "Fred","Europe/London",""))))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With