【问题标题】:glm `predict()` error: no applicable method for 'predict' applied to an object of class "list"glm`predict()`错误:没有适用于“预测”的方法应用于“列表”类的对象
【发布时间】:2017-01-10 23:39:22
【问题描述】:

我在控制输入预测函数的对象类型时遇到问题。这是生成glm 对象的简化函数。

fitOneSample <- function(x,data,sampleSet)
{
  #how big of a set are we going to analyze? Pick a number between 5,000 & 30,000, then select that many rows to study
  sampleIndices <- 1:5000

  #now randomly pick which columns to study
  colIndices <- 1:10

  xnames <- paste(names(data[,colIndices]),sep = "")
  formula <- as.formula(paste("target ~ ", paste(xnames,collapse = "+")))
  glm(formula,family=binomial(link=logit),data[sampleIndices,])
}

myFit <- fitOneSample(1,data,sampleSet)
fits <- sapply(1:2,fitOneSample,data,sampleSet)
all.equal(myFit,fits[,1]) #different object types

#this works
probability <- predict(myFit,newdata = data)

#this doesn't
probability2 <- predict(fits[,1],newdata = data)
# Error in UseMethod("predict") :
# no applicable method for 'predict' applied to an object of class "list"

如何访问 fits[,1] 中的列,以便使用 predict 函数获得与 myFit 相同的结果?

【问题讨论】:

  • 尝试fits &lt;- lapply(1:2,fitOneSample,data,sampleSet),然后尝试probability2 &lt;- predict(fits[[1]],newdata = data)
  • 谢谢@cryo111。效果很好。

标签: r regression glm predict


【解决方案1】:

我想我现在可以恢复你的情况了。

fits <- sapply(names(trees),
               function (y) do.call(lm, list(formula = paste0(y, " ~ ."), data = trees)))

这里以内置数据集trees为例,拟合三个线性模型:

Girth ~ Height + Volume
Height ~ Girth + Volume
Volume ~ Height + Girth

由于我们使用了sapply,并且每次迭代都返回相同的lm对象,或者一个长度为12的列表,结果将被简化为12 * 3矩阵:

class(fits)
# "matrix"

dim(fits)
# 12  3

矩阵索引fits[, 1] 有效。

如果您检查str(fits[, 1]),它几乎看起来就像一个普通的lm 对象。但如果你进一步检查:

class(fits[, 1])
# "list"

嗯?它没有“lm”类!因此,当你调用泛型函数predict时,S3调度方法会失败:

predict(x)
#Error in UseMethod("predict") : 
#  no applicable method for 'predict' applied to an object of class "list"

这可以看作是sapply 具有破坏性的一个很好的例子。我们想要lapply,或者至少是sapply(..., simplify = FALSE)

fits <- lapply(names(trees),
               function (y) do.call(lm, list(formula = paste0(y, " ~ ."), data = trees)))

lapply 的结果更容易理解。它是一个长度为 3 的列表,其中每个元素都是一个 lm 对象。我们可以通过fits[[1]] 访问第一个模型。现在一切正常:

class(fits[[1]])
# "lm"

predict(fits[[1]])
#        1         2         3         4         5         6         7         8 
# 9.642878  9.870295  9.941744 10.742507 10.801587 10.886282 10.859264 10.957380 
#        9        10        11        12        13        14        15        16 
#11.588754 11.289186 11.946525 11.458400 11.536472 11.835338 11.133042 11.783583 
#       17        18        19        20        21        22        23        24 
#13.547349 12.252715 12.603162 12.765403 14.002360 13.364889 14.535617 15.016944 
#       25        26        27        28        29        30        31 
#15.628799 17.945166 17.958236 18.556671 17.229448 17.131858 21.888147 

你可以修复你的代码

fits <- lapply(1:2,fitOneSample,data,sampleSet)
probability2 <-predict(fits[[1]],newdata = data)

【讨论】:

  • 谢谢。我的主要问题是在循环期间保留结构。你的 cmets 让我意识到 sapply 破坏了结构 - 很高兴知道。我修改了之前的函数以使用 lapply。
猜你喜欢
  • 2016-12-02
  • 2019-07-22
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 2017-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多