下面的ConvertToLocal
函数采用Names
和Times
的数据框,并使用一些if语句进行时区转换。我如何对此进行矢量化,以便不使用循环?
谢谢。
以下是代码:
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)
答案 0 :(得分:4)
另一种方法是创建一个查找表,然后使用mapply
使用data.table以便于合并
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 :(得分:3)
您可以轻松地将3个转换作为3个单独的矢量化步骤。
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
}
给出了示例数据
> 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
答案 2 :(得分:2)
试试这个:
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)
}
答案 3 :(得分:1)
这是另一种选择,使用mapply
和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",""))))