如何解决while(time <= time_end)中的「需TRUE/FALSE却得缺失值」错误?
问题描述
- 已在逻辑语句中处理NULL值,但仍触发报错,数据中存在无法删除的NULL值
Visual是包含整数格式时间(例如8:00对应800)及其他字符型数据的DataFramefinal_1和final_2是Visual的空版本- 还需编写时间逻辑:当时间的分钟部分达到60时,小时部分增加100(例如850+20需得到910,而非870)
运行代码
for (i in 1:nrow(Visual)){ time <- Visual[i,]$Start_Time time_end <- Visual[i,]$End_Time if(is.null(time)){ time <- min_time if(is.null(time_end)){ while(time <= max_time){ final_2[i,]$Time <- time final_2[i,]$Appointment_AIM <- Visual[i,]$Appointment final_2[i,]$AIM_Abbreviation <- Visual[i,]$Abbreviation final_2[i,]$Standard_Duration <- Visual[i,]$Standard_Duration final_2[i,]$Booking_Factor <- Visual[i,]$Booking_Factor final_2[i,]$Appointment_Categories_ACM <- Visual[i,]$Appointment_Categories final_2[i,]$ACM_Abbreviation <- Visual[i,]$ACM_Abbreviation final_2[i,]$Color_Code <- Visual[i,]$Color_Code final_1 <- rbind(final_1, final_2) time <- time + Visual[i,]$Standard_Duration } }else{ while(time <= time_end){ final_2[i,]$Time <- time final_2[i,]$Appointment_AIM <- Visual[i,]$Appointment final_2[i,]$AIM_Abbreviation <- Visual[i,]$Abbreviation final_2[i,]$Standard_Duration <- Visual[i,]$Standard_Duration final_2[i,]$Booking_Factor <- Visual[i,]$Booking_Factor final_2[i,]$Appointment_Categories_ACM <- Visual[i,]$Appointment_Categories final_2[i,]$ACM_Abbreviation <- Visual[i,]$Abbreviation final_2[i,]$Color_Code <- Visual[i,]$Color_Code final_1 <- rbind(final_1, final_2) time <- time + Visual[i,]$Standard_Duration } } }else{ if(is.null(time_end)){ while(time <= max_time){ final_2[i,]$Time <- time final_2[i,]$Appointment_AIM <- Visual[i,]$Appointment final_2[i,]$AIM_Abbreviation <- Visual[i,]$Abbreviation final_2[i,]$Standard_Duration <- Visual[i,]$Standard_Duration final_2[i,]$Booking_Factor <- Visual[i,]$Booking_Factor final_2[i,]$Appointment_Categories_ACM <- Visual[i,]$Appointment_Categories final_2[i,]$ACM_Abbreviation <- Visual[i,]$Abbreviation final_2[i,]$Color_Code <- Visual[i,]$Color_Code final_1 <- rbind(final_1, final_2) time <- time + Visual[i,]$Standard_Duration } }else{ while(time <= time_end){ final_2[i,]$Time <- time final_2[i,]$Appointment_AIM <- Visual[i,]$Appointment final_2[i,]$AIM_Abbreviation <- Visual[i,]$Abbreviation final_2[i,]$Standard_Duration <- Visual[i,]$Standard_Duration final_2[i,]$Booking_Factor <- Visual[i,]$Booking_Factor final_2[i,]$Appointment_Categories_ACM <- Visual[i,]$Appointment_Categories final_2[i,]$ACM_Abbreviation <- Visual[i,]$Abbreviation final_2[i,]$Color_Code <- Visual[i,]$Color_Code final_1 <- rbind(final_1, final_2) time <- time + Visual[i,]$Standard_Duration } } } }
报错信息
Error in while (NA) { : missing value where TRUE/FALSE needed
问题分析与解决
错误原因
- NULL与NA混淆:在R的DataFrame中,缺失值默认存储为
NA而非NULL,原代码用is.null()无法检测到NA,导致循环条件中出现NA,触发报错。 - 时间进位逻辑缺失:原代码直接对时间整数做加法,未处理分钟满60进1小时的需求。
- 循环效率低下:在循环中反复使用
rbind()拼接数据框,会大幅降低运行效率,尤其当数据量较大时。
解决步骤
1. 替换缺失值检测逻辑
将is.null()替换为is.na(),或同时检测NULL和NA,确保覆盖所有缺失值场景:
# 处理Start_Time的缺失值 if (is.null(time) || is.na(time)) { time <- min_time } # 处理End_Time的缺失值 if (is.null(time_end) || is.na(time_end)) { time_end <- max_time }
2. 实现时间进位函数
编写函数处理时间加法后的进位逻辑:
add_time <- function(current_time, duration) { # 拆分小时和分钟 hour <- floor(current_time / 100) minute <- current_time %% 100 # 计算新的分钟和小时 total_minute <- minute + duration new_hour <- hour + floor(total_minute / 60) new_minute <- total_minute %% 60 # 组合成整数格式时间 return(new_hour * 100 + new_minute) }
3. 重构循环逻辑
简化重复代码,优化数据拼接方式:
# 预分配结果数据框,避免循环内频繁rbind final_1 <- data.frame(matrix(nrow = 0, ncol = 8)) colnames(final_1) <- c("Time", "Appointment_AIM", "AIM_Abbreviation", "Standard_Duration", "Booking_Factor", "Appointment_Categories_ACM", "ACM_Abbreviation", "Color_Code") for (i in 1:nrow(Visual)) { time <- Visual[i,]$Start_Time time_end <- Visual[i,]$End_Time duration <- Visual[i,]$Standard_Duration # 统一处理缺失值 if (is.null(time) || is.na(time)) time <- min_time if (is.null(time_end) || is.na(time_end)) time_end <- max_time # 循环生成时间序列 while (time <= time_end) { # 构造当前行数据 new_row <- data.frame( Time = time, Appointment_AIM = Visual[i,]$Appointment, AIM_Abbreviation = Visual[i,]$Abbreviation, Standard_Duration = duration, Booking_Factor = Visual[i,]$Booking_Factor, Appointment_Categories_ACM = Visual[i,]$Appointment_Categories, ACM_Abbreviation = Visual[i,]$ACM_Abbreviation, Color_Code = Visual[i,]$Color_Code ) # 合并到结果 final_1 <- rbind(final_1, new_row) # 计算下一个时间(带进位) time <- add_time(time, duration) } }
内容的提问来源于stack exchange,提问作者Michael Schulte
相关产品推荐
相关产品推荐

