Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to vectorize this loop

Tags:

r

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)
like image 517
user3022875 Avatar asked Feb 03 '15 23:02

user3022875


People also ask

What does it mean to vectorize a loop?

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.

What does it mean to vectorize data?

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).

How do you vectorize in C++?

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 in python?

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.


4 Answers

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 
like image 131
mnel Avatar answered Nov 15 '22 08:11

mnel


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
like image 39
Gavin Simpson Avatar answered Nov 15 '22 08:11

Gavin Simpson


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)
} 
like image 35
Jthorpe Avatar answered Nov 15 '22 07:11

Jthorpe


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",""))))
like image 30
agstudy Avatar answered Nov 15 '22 07:11

agstudy