尝试从 R 中的 GLM 预测新数据时出现持续错误

Getting persistent error when trying to predict new data from a GLM in R

我在尝试使用 R 中的 predict 预测新数据的结果时收到持续错误“错误:变量‘x1’、‘x2’、‘x3’指定为不同类型”。我已经 运行 这段代码在其他模型上取得了成功,但出于某种原因我无法弄清楚这个代码有什么问题。我用以下代码复制了这个问题:

# make data
set.seed(19870630)
n <- 1000
df <- data.frame(y = rgamma(n, shape = .5, rate = 1),
                 #runif(n, 0, 1), # trows same error
                 x1 = runif(n, 0, 100),
                 x2 = runif(n, 0, 100),
                 x3 = runif(n, -1, 1))

df$x2 <-  df$x1*df$x1

# refine data by scaling
df$x1 <- scale(df$x1, center = TRUE)
df$x2 <- scale(df$x2, center = TRUE)
df$x3 <- scale(df$x3, center = TRUE)

# double check
head(df); plot(df)

# fit model
mod <- glm(y ~ x1 + x2 + x3, data = df, family=Gamma(link="log"))

# confirm, success
summary(mod)


# make data to retain predictions
## first get realistic ranges of variables of interest, other vars will be held at mean
(x1_span <- c(rep(seq(min(df$x1), max(df$x1)), length = 50)))
(x2_span <- c(rep(seq(min(df$x2), max(df$x2)), length = 50)))


df_pred_x1_x2 <- data.frame(x1 = x1_span,
                            x2 = x2_span,
                            x3 = mean(df$x3))

# generate function for prediction ml predicted values
predict_fun <- function(my_glm) {
  predict(my_glm, newdata = df_pred_x1_x2)   # this is predict.glm
}

df_pred_x1_x2$y_value_pred <- predict_fun(mod) # error

# "Error: variables ‘x1’, ‘x2’, ‘x3’ were specified with different types from the fit"
                                                      
# End March 8, 2021

如有任何帮助,我们将不胜感激。

这是因为scale()在下面x1的描述中将变量变成了单列矩阵(注意num [1:1000, 1])。老实说,我不确定这何时会或不会造成麻烦......

str(df)
'data.frame':   1000 obs. of  4 variables:
 $ y : num  ...
 $ x1: num [1:1000, 1] 1.448 -1.702 -0.559 -1.147 0.732 ...
  ..- attr(*, "scaled:center")= num 49.2
  ..- attr(*, "scaled:scale")= num 28.5
...

您可以通过调用 df <- lapply(df,drop) 删除额外的维度来解决这个问题( 适合模型之前)。 @dlaggy 指出您还可以定义自己的缩放函数 (function(x) (x-mean(x))/sd(x));你也可以定义

myscale <- function(...) drop(scale(...))

请注意,与使用 c()(我在之前的回答中建议过)不同,它会降低尺寸 其他属性,drop() 只会降低尺寸- 这样您就可以在进行过程中将 scale/center 属性与数据保持在一起。