使用R的modeltime包遇Date索引含NA错误,求解决方案
解决Modeltime时间序列可视化与校准的Date索引NA报错问题
问题描述
使用R的modeltime包进行时间序列分析时,遇到两类核心错误:
- 可视化数据拆分时触发
validate_index()报错,提示Column 'Date' (index) must not contain NA - 模型校准阶段所有模型均因相同错误失败
已删除数据集中2个Aluminium_Prices列的NA,但问题仍未解决。相关代码及错误信息如下:
数据处理与拆分代码
# Webscrape webpage <- read_html("https://www.westmetall.com/en/markdaten.php?action=table&field=LME_Al_cash") alu_table <- html_nodes(webpage, "table") %>% html_table(fill = TRUE) alu_df <- map_dfr(alu_table, magrittr::extract, c("date", "LME Aluminium Cash-Settlement")) # Names names(alu_df)[1] <- "Date" names(alu_df)[2] <- "Aluminium_Prices" # Clear rows in data frame alu_df_cleaned <- alu_df %>% filter(Date != "date" & Aluminium_Prices != "LME Aluminium Cash-Settlement") # Change Date type alu_df_cleaned$Date <- dmy(alu_df_cleaned$Date) # Proper structure of integers to translate them to the numeric class alu_df_cleaned$Aluminium_Prices <- gsub(",", "", alu_df_cleaned$Aluminium_Prices) alu_df_cleaned$Aluminium_Prices <- as.numeric(alu_df_cleaned$Aluminium_Prices) # Sorting prices by Date alu_df_cleaned <- alu_df_cleaned %>% arrange(Date) # Check if there are any NA's sum(is.na(alu_df_cleaned$Aluminium_Prices)) df_na <- as.data.frame( cbind( map( map(alu_df_cleaned$Aluminium_Prices, is.na), sum) ) ) rownames(subset(df_na, df_na$V1 != 0)) # Convert to tibble alu_ts_data <- alu_df_cleaned %>% mutate(row_name = row_number()) %>% tsibble::as_tsibble(index = Date, key = row_name) # Drop NA's from the dataset alu_ts_data <- alu_ts_data %>% drop_na() # Split the data into train and test set.seed(1353) splits <- initial_time_split(alu_ts_data) train <- training(splits) test <- testing(splits) # Visualise the Splits splits %>% tk_time_series_cv_plan() %>% plot_time_series_cv_plan(.date_var = Date, .value = Aluminium_Prices)
可视化报错信息
Error in `validate_index()`: ! Column `Date` (index) must not contain `NA`. Backtrace: 1. splits %>% tk_time_series_cv_plan() %>% ... 10. tidyr:::unnest.data.frame(., .value) 11. tidyr::unchop(...) 12. tidyr:::df_unchop(...) 13. vctrs::list_unchop(col, ptype = col_ptype) 14. vctrs (local) `<fn>`() 16. tsibble:::vec_restore.tbl_ts(x = x, to = to) 17. tsibble::build_tsibble(...) 18. tsibble:::validate_index(tbl, !!qindex) Error in validate_index(tbl, !!qindex) :
模型校准代码与报错
# Multiple models # Auto ARIMA Model arima_auto_fit <- arima_reg() %>% set_engine("auto_arima") %>% fit(Aluminium_Prices ~ Date, data = train) # Boosted ARIMA Model arima_boost_fit <- arima_boost() %>% set_engine("auto_arima_xgboost") %>% fit(Aluminium_Prices ~ Date, data = train) # Exponential Smoothing Model ets_fit <- exp_smoothing() %>% set_engine("ets") %>% fit(Aluminium_Prices ~ Date, data = train) # Prophet Model prophet_fit <- prophet_reg() %>% set_engine("prophet") %>% fit(Aluminium_Prices ~ Date, data = train) # Linear Model lm_fit <- linear_reg() %>% set_engine("lm") %>% fit(Aluminium_Prices ~ Date, data = train) # Put in Table and Calibrate models_tbl <- modeltime_table( arima_auto_fit, arima_boost_fit, ets_fit, prophet_fit, lm_fit ) # Calibrate calibrate_tbl <- models_tbl %>% modeltime::modeltime_calibrate(new_data = test, quiet = FALSE)
Error: Column `Date` (index) must not contain `NA`. Error: Column `Date` (index) must not contain `NA`. Error: Column `Date` (index) must not contain `NA`. Error: Column `Date` (index) must not contain `NA`. Error: Column `Date` (index) must not contain `NA`. ── Model Calibration Failure Report ──────────────────────── All models failed Modeltime Calibration: - Model 1: Failed Calibration. - Model 2: Failed Calibration. - Model 3: Failed Calibration. - Model 4: Failed Calibration. - Model 5: Failed Calibration. Potential Solution: Use `modeltime_calibrate(quiet = FALSE)` AND Check the Error/Warning Messages for clues as to why your model(s) failed calibration. ── End Model Calibration Failure Report ──────────────────── Error in `validate_modeltime_calibration()`: ! All models failed Modeltime Calibration. Backtrace: 1. models_tbl %>% ... 3. modeltime:::modeltime_calibrate.mdl_time_tbl(...) 4. modeltime:::validate_modeltime_calibration(ret) Error in validate_modeltime_calibration(ret)
排查原因
- 仅检查数值列NA,忽略Date列:代码中只验证了
Aluminium_Prices的NA,但dmy()转换日期时可能因格式不匹配生成NA,这些NA未被检测处理。 - tsibble的key设置不合理:单变量时间序列无需设置
key = row_name,这会让tsibble识别为多序列,后续拆分处理时出现索引混乱。 - drop_na()处理不彻底:原代码中
drop_na()默认删除含NA的行,但Date列的NA可能在转换为tsibble后才暴露,未被彻底清理。
解决方案
步骤1:全面检查并清理Date列的NA
替换原有NA检查代码,同时验证Date列:
# 检查所有列的NA数量 colSums(is.na(alu_df_cleaned)) # 仅保留Date和Aluminium_Prices均非NA的行 alu_df_cleaned <- alu_df_cleaned %>% filter(!is.na(Date) & !is.na(Aluminium_Prices))
步骤2:修正tsibble转换逻辑
单变量时间序列无需设置key,直接转换:
# 转换为tsibble(单序列无需key) alu_ts_data <- alu_df_cleaned %>% tsibble::as_tsibble(index = Date)
步骤3:重新执行数据拆分与后续操作
# 重新拆分数据 set.seed(1353) splits <- initial_time_split(alu_ts_data) train <- training(splits) test <- testing(splits) # 验证训练集和测试集的Date列无NA sum(is.na(train$Date)) sum(is.na(test$Date)) # 重新可视化拆分 splits %>% tk_time_series_cv_plan() %>% plot_time_series_cv_plan(.date_var = Date, .value = Aluminium_Prices) # 重新训练模型并校准 models_tbl <- modeltime_table( arima_auto_fit, arima_boost_fit, ets_fit, prophet_fit, lm_fit ) calibrate_tbl <- models_tbl %>% modeltime::modeltime_calibrate(new_data = test, quiet = FALSE)
额外验证:检查日期格式一致性
确保所有日期转换成功,无异常值:
# 查看Date列的范围和类型 range(alu_df_cleaned$Date) class(alu_df_cleaned$Date) # 检查是否有无法转换的日期字符串 bad_dates <- alu_df %>% filter(Date != "date") %>% mutate(Date_parsed = dmy(Date, quiet = TRUE)) %>% filter(is.na(Date_parsed)) print(bad_dates)
内容的提问来源于stack exchange,提问作者AmAzing
相关产品推荐
相关产品推荐

