它可以在没有任何包的情况下在一行中完成,或者ifelse
如果我们使用命名向量
df$Date <- with(df, Date - setNames(rep(0:2, c(5, 1, 1)), 1:7)[format(Date, "%u")])
df
# Ticker Date mean_PX_ASK mean_PX_BID Agency
#1 ABNANV 2007-03-02 102.0 102.0 Moody's
#2 ABNANV 2007-03-02 102.0 102.0 Moody's
#3 ABNANV 2007-03-12 102.0 102.0 Moody's
#4 ABNANV 2007-03-12 102.0 102.0 Moody's
#5 ABNANV 2008-09-17 88.9 88.4 Fitch
#6 ABNANV 2008-09-17 88.9 88.4 Fitch
基准
使用更大的数据集
df1 <- df[rep(seq_len(nrow(df)), 1e7), ]
system.time({
df1 %>%
mutate(Day = weekdays(Date),
Date = case_when(Day == "Saturday" ~ Date - 1,
Day == "Sunday" ~ Date - 2,
TRUE ~ Date)) %>%
select(-Day)
})
# user system elapsed
# 41.468 6.881 49.588
system.time({
with(df1, Date - setNames(rep(0:2, c(5, 1, 1)), 1:7)[format(Date, "%u")])
})
# user system elapsed
# 27.456 2.785 30.490
与microbenchmark
,
library(microbenchmark)
microbenchmark(
rs = df1 %>%
mutate(Day = weekdays(Date),
Date = case_when(Day == "Saturday" ~ Date - 1,
Day == "Sunday" ~ Date - 2,
TRUE ~ Date)) %>%
select(-Day),
ak = with(df1, Date - setNames(rep(0:2, c(5, 1, 1)), 1:7)[format(Date, "%u")]),
times = 10L, unit = "relative")
#Unit: relative
# expr min lq mean median uq max neval cld
# rs 1.401658 1.437164 1.446403 1.421731 1.512451 1.467511 10 b
# ak 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 10 a
数据
df <- structure(list(Ticker = c("ABNANV", "ABNANV", "ABNANV", "ABNANV",
"ABNANV", "ABNANV"), Date = structure(c(13575, 13576, 13584,
13584, 14139, 14139), class = "Date"), mean_PX_ASK = c(102, 102,
102, 102, 88.9, 88.9), mean_PX_BID = c(102, 102, 102, 102, 88.4,
88.4), Agency = c("Moody's", "Moody's", "Moody's", "Moody's",
"Fitch", "Fitch")), row.names = c("1", "2", "3", "4", "5", "6"
), class = "data.frame")