r - 对值进行操作时如何忽略空单元格或 NA
问题描述
我正在尝试计算数据框中两个日期之间的工作日数。
我正在使用这里给出的解决方案。当所有列中的日期都可用时,该解决方案有效,但如果缺少任何日期,则没有结果。
这是正在使用的代码:
library(dplyr)
# The macro to calculate working days
Nweekdays <- Vectorize(function(a, b)
sum(!weekdays(seq(a, b, "days")) %in% c("Saturday", "Sunday")))
# Sample data frame
id = c("ID1", "ID2", "ID3")
startDate = c("2019-08-01", "2019-08-06", "2019-08-10")
endDate = c("2019-08-05", "2019-08-15", "2019-08-20")
df = data.frame(id, startDate, endDate)
# Using dplyr to coerce to Date and run macro
df <- df %>%
mutate(startDate = as.Date(startDate)) %>%
mutate(endDate = as.Date(endDate)) %>%
mutate(workingdays = Nweekdays(startDate, endDate))
该代码正常工作,并为我提供了一个包含工作日的新专栏。但如果其中一个日期缺失或不适用,例如
startDate = c("2019-08-01", "", "2019-08-10")
然后我得到
Evaluation error: 'to' must be a finite number.
并且没有生成新列。我想要缺失值的空结果,但所有其他值的正确结果。我敢肯定我错过了一些基本的东西,所以为此道歉!
解决方案
您只需要更新您的函数以处理非日期值,因此它只尝试计算 a 和 b 是否都是日期:
Nweekdays <- Vectorize(function(a, b) {
if (!is.na(a) & !is.na(b)) {
sum(!weekdays(seq(a, b, "days")) %in% c("Saturday", "Sunday"))
} else {
return(NA)
}
})
您可以使用一些更严格的验证形式,而不是!is.na()
使用类似lubridate::is.Date()
的方法,但这是一个基本解决方案,当您as.Date()
在 mutate 行中调用时,任何非日期值都将转换为 NA。
推荐阅读
- mysql - dense_rank() 和 max,哪个更好找到 Nth 最高薪水(如果没有结果则返回 null)
- kubernetes - 有没有办法查看谁在 Kubernetes 中运行了 pods/jobs?
- cypress - 如何仅在系统范围内读取 cypress 中的 testdata/Json 一次?
- node.js - 如何在 Visual Studio Code 中调试 k6 测试脚本?
- python - Django:显示可下载的自定义日志文件
- mysql - 制作Mysql数据库(外键)
- javascript - TypeError:无法在打字稿中分配给对象“[object Array]”的只读属性“0”
- python - 重塑图像分割大小
- fiware - 在哪里可以找到标准化的 NGSI-LD 实体类型及其属性
- django - 升级到 PostgreSQL 后 ImageField 的默认值不起作用(Django)