首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在检查日期是否为NA时,bizdays::adjust.previous的意外行为

在检查日期是否为NA时,bizdays::adjust.previous的意外行为
EN

Stack Overflow用户
提问于 2022-03-15 08:36:52
回答 1查看 78关注 0票数 0

我试图使用bizday包将dataframe中的日期转换为工作日。这个dataframe可能有一些缺失的值(NA),所以我添加了一个ifelse语句来忽略这些空单元格,但是它似乎破坏了代码,我不知道为什么。

这是错误的一个小例子:

代码语言:javascript
复制
library(bizdays)
library(dplyr)

holidays <- c("2022-03-01",
              "2022-03-07",
              "2022-03-08",
              "2022-03-25")

start_date = as.Date("01/01/2010", format = "%d/%m/%Y")
end_date   = as.Date("01/01/2060", format = "%d/%m/%Y")

calendar <- create.calendar("my_cal",
                            holidays =  holidays,
                            weekdays =c("saturday", "sunday"),
                            start.date = start_date,
                            end.date = end_date)

bizdays.options$set(default.calendar="my_cal")


date_1 <- "2022-03-13" # sunday
print(adjust.previous(date_1)) # friday "2022-03-11"

days <- c()
for (i in c(1:31)) {
  days <- c(days, paste("2022-03-", formatC(i, width = 2, flag = '0'), sep = ""))
}

df <- data.frame(days = days)

df_1 <- df %>% mutate(days_1 = adjust.previous(days))

head(df_1) # correct
#        days     days_1
#1 2022-03-01 2022-02-28
#2 2022-03-02 2022-03-02
#3 2022-03-03 2022-03-03
#4 2022-03-04 2022-03-04
#5 2022-03-05 2022-03-04
#6 2022-03-06 2022-03-04

df_2 <- df %>% mutate(days_2 = ifelse(is.na(days),
                                      days,
                                      adjust.previous(days)))

head(df_2) # date is converted to a number
#        days days_2
#1 2022-03-01  19051
#2 2022-03-02  19053
#3 2022-03-03  19054
#4 2022-03-04  19055
#5 2022-03-05  19055
#6 2022-03-06  19055
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-15 09:05:53

这与bizdays包无关,而是ifelse()如何以数值形式返回类Date的对象。参见此示例:

代码语言:javascript
复制
class(Sys.Date()) # Date
ifelse(TRUE, Sys.Date(), Sys.Date()) # 19066
class(ifelse(TRUE, Sys.Date(), Sys.Date())) # numeric

相反:

代码语言:javascript
复制
if(TRUE) class(Sys.Date()) # Date

在您的例子中,在我看来,ifelse()是不必要的,因为adjust.previous处理NA值:

代码语言:javascript
复制
df$days[1] = NA
df_2 <- df %>% mutate(
    days_2 = adjust.previous(days)
)

# Seems to work
head(df_2)
#         days     days_2
# 1       <NA>       <NA>
# 2 2022-03-02 2022-03-02
# 3 2022-03-03 2022-03-03
# 4 2022-03-04 2022-03-04
# 5 2022-03-05 2022-03-04
# 6 2022-03-06 2022-03-04

但是,如果这不适用于您的实际数据,我将离开dplyr世界,这个世界很棒,但在细分列时稍微弱一些,然后在基R中这样做:

代码语言:javascript
复制
df_3  <- df 
df_3$days_3  <- as.Date(0, origin = "1970-01-01") # Create date column
df_3$days_3[is.na(df_3$days)]  <- NA # Fill NA
df_3$days_3[!is.na(df_3$days)]  <- adjust.previous(df_3$days[!is.na(df_3$days)]) # Fill values

# Output as above
head(df_3)
#         days     days_3
# 1       <NA>       <NA>
# 2 2022-03-02 2022-03-02
# 3 2022-03-03 2022-03-03
# 4 2022-03-04 2022-03-04
# 5 2022-03-05 2022-03-04
# 6 2022-03-06 2022-03-04
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71479182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档