R语言:如何筛选/标记包含全部工作日数据的周?
问题分析
你的for循环逻辑存在两个核心问题:
- 每次循环都在检查整个数据集的
day是否全部属于工作日列表,而非针对当前周(i对应的分组)的日期进行判断; - 循环中每次都会覆盖整个
flag列,最终结果是全局判断的结论(你的数据集中存在非工作日,所以all(reprex$day %in% weekdays)始终为FALSE,导致所有标记为0)。
另外,cbind会将数据转换为字符矩阵,再转为data.frame时会把week_num变成字符型,建议直接用data.frame(week_num, day)创建数据集,避免类型问题。
解决方案
方法1:使用dplyr(推荐,适合大型数据集)
利用分组操作高效判断每个周是否包含全部工作日:
library(dplyr) # 构造数据集(避免cbind导致的类型问题) week_num <- c(1,1,1,1,1,2,2,2,3,3,3,3) day <- c("Monday", "Tuesday", "Thursday", "Wednesday", "Friday", "Friday", "Sunday", "Saturday", "Thursday", "Wednesday", "Tuesday", "Sunday") reprex <- data.frame(week_num, day) weekdays <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") # 分组判断并生成标记列 reprex <- reprex %>% group_by(week_num) %>% mutate(flag = ifelse(all(weekdays %in% day), 1, 0)) %>% ungroup() print(reprex)
关键逻辑:all(weekdays %in% day)用于检查当前分组的日期是否包含所有工作日,而非检查所有日期是否都是工作日。
方法2:使用base R(无需额外包)
用ave函数实现分组判断:
week_num <- c(1,1,1,1,1,2,2,2,3,3,3,3) day <- c("Monday", "Tuesday", "Thursday", "Wednesday", "Friday", "Friday", "Sunday", "Saturday", "Thursday", "Wednesday", "Tuesday", "Sunday") reprex <- data.frame(week_num, day) weekdays <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") # 生成标记列 reprex$flag <- with(reprex, ave(day, week_num, FUN = function(x) { as.integer(all(weekdays %in% x)) })) print(reprex)
方法3:修正你的for循环(不推荐,大型数据集效率低)
如果坚持用循环,需要针对每个周的子集进行判断,并仅更新对应分组的标记:
week_num <- c(1,1,1,1,1,2,2,2,3,3,3,3) day <- c("Monday", "Tuesday", "Thursday", "Wednesday", "Friday", "Friday", "Sunday", "Saturday", "Thursday", "Wednesday", "Tuesday", "Sunday") reprex <- data.frame(week_num, day) weekdays <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") # 初始化标记列为0 reprex$flag <- 0 for (i in unique(reprex$week_num)) { # 获取当前周的所有日期 current_days <- reprex$day[reprex$week_num == i] # 判断是否包含全部工作日 if (all(weekdays %in% current_days)) { # 更新当前周的标记为1 reprex$flag[reprex$week_num == i] <- 1 } } print(reprex)
内容的提问来源于stack exchange,提问作者Abbey A.
相关产品推荐
相关产品推荐

