使用虚拟变量做时间序列季节性调整时遇mutate()报错求助
问题
我想用虚拟变量对6年月度时间序列f1value做季节性调整,先执行了以下代码提取月度平均差异:
df_dummy <- dummy_cols(df, select_columns = "month") fit <- lm(data = df_dummy, formula = f1value ~ month_1 + month_2 + month_3 + month_4 + month_5 + month_6 + month_7 + month_8 + month_9 + month_10 + month_11 + month_12)
接着用模型结果计算调整后值时,运行以下代码报错:'names' attribute [1] must be the same length as the vector [0]
df_dummy %>% mutate(f1val_season_adj = # create new col case_when( month_1 == 1 ~ f1value - 2925, # if Jan, adj f1val by the estimate given in model month_2 == 1 ~ f1value - 3842, month_3 == 1 ~ f1value + 1235, month_4 == 1 ~ f1value + 6440, month_5 == 1 ~ f1value + 5938, month_6 == 1 ~ f1value + 6752, month_7 == 1 ~ f1value + 9491, month_8 == 1 ~ f1value + 7679, month_9 == 1 ~ f1value + 1596, month_10 == 1 ~ f1value + 3669, month_11 == 1 ~ f1value + 1735, month_12 == 1 ~ f1value # Dec. gets the Original value, as est. are based off month 12 base ) )
不清楚错误涉及的向量或names属性是什么。
问题分析与解决方法
核心报错原因
- 虚拟变量列匹配问题:
dummy_cols生成的列名可能和你写的month_1~month_12不匹配——比如如果原始month列是字符型(如"Jan"),生成的列名会是month_Jan,此时case_when里的条件找不到对应列,返回空向量。 case_when未覆盖所有行:如果存在部分行的所有month_*都不等于1(比如month列有缺失值、虚拟变量生成错误),case_when会返回长度为0的结果,但mutate要求结果长度和原数据行数一致,从而触发names长度不匹配的错误。- 手动系数与模型冲突:你手动输入的2925等系数可能和
lm模型的实际估计值不对应,甚至因为模型自动剔除了一个虚拟变量(共线性问题),导致部分系数不存在,间接引发计算错误。
修正步骤
1. 检查并确认虚拟变量列
先运行colnames(df_dummy)查看生成的列名,确保和case_when中的条件列完全一致。如果是字符型月份,要把条件改成对应列名,比如month_January == 1。
2. 给case_when添加默认分支
在最后加TRUE ~ f1value(或合理默认值),确保所有行都能得到结果,避免返回空向量:
df_dummy %>% mutate(f1val_season_adj = case_when( month_1 == 1 ~ f1value - 2925, month_2 == 1 ~ f1value - 3842, month_3 == 1 ~ f1value + 1235, month_4 == 1 ~ f1value + 6440, month_5 == 1 ~ f1value + 5938, month_6 == 1 ~ f1value + 6752, month_7 == 1 ~ f1value + 9491, month_8 == 1 ~ f1value + 7679, month_9 == 1 ~ f1value + 1596, month_10 == 1 ~ f1value + 3669, month_11 == 1 ~ f1value + 1735, month_12 == 1 ~ f1value, TRUE ~ f1value # 覆盖所有未匹配的情况 ) )
3. 自动调用模型系数,避免手动输入
直接从fit模型中提取系数,避免手动输入错误:
# 提取月度虚拟变量系数,给基准月份(如month_12)补0 season_coefs <- coef(fit) season_coefs <- c(season_coefs, setNames(0, "month_12"))[paste0("month_", 1:12)] # 用模型系数自动计算调整值 df_dummy <- df_dummy %>% mutate( season_effect = case_when( month_1 ==1 ~ season_coefs["month_1"], month_2 ==1 ~ season_coefs["month_2"], month_3 ==1 ~ season_coefs["month_3"], month_4 ==1 ~ season_coefs["month_4"], month_5 ==1 ~ season_coefs["month_5"], month_6 ==1 ~ season_coefs["month_6"], month_7 ==1 ~ season_coefs["month_7"], month_8 ==1 ~ season_coefs["month_8"], month_9 ==1 ~ season_coefs["month_9"], month_10 ==1 ~ season_coefs["month_10"], month_11 ==1 ~ season_coefs["month_11"], month_12 ==1 ~ season_coefs["month_12"], TRUE ~ 0 ), f1val_season_adj = f1value - season_effect )
4. 简化建模流程(更推荐)
无需手动生成虚拟变量,用factor(month)让lm自动处理:
# 直接用因子型月份建模 fit <- lm(f1value ~ factor(month), data = df) # 计算季节性调整值 df <- df %>% mutate( # 提取季节性效应:拟合值减去基准组均值(截距项) season_effect = predict(fit) - coef(fit)[1], f1val_season_adj = f1value - season_effect )
内容的提问来源于stack exchange,提问作者shrey_shankar
相关产品推荐
相关产品推荐

