2015-02-03 18 views
5

La funzione ConvertToLocal in basso accetta un frame di dati di Names e Times e esegue una conversione di fuso orario con alcune istruzioni if. Come posso vettorizzare questo in modo da non usare i loop?Come vettorializzare questo ciclo

Grazie.

Ecco il codice:

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) 

risposta

2

provare questo:

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) 
} 
1

Ecco un'altra opzione, utilizzando mapply e 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","")))) 
3

Si può facilmente fare le 3 trasformazioni come 3 fasi vettoriali separate.

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 
} 

che dà, per i dati di esempio

> 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 
4

altro approccio sarebbe quello di creare una tabella di ricerca e quindi utilizzare mapply

Uso data.table per facilità di fondere

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 
+1

approccio piacevole con una tabella di ricerca – Rentrop

Problemi correlati