簡體   English   中英

如何在R中為統計模型對象編寫S3公式方法

[英]How to write an S3 formula method for a statistical model object in R

我有一個函數可以對多元線性模型中的協方差矩陣的相等性進行Box的M檢驗。 我想使用公式方法將其轉換為S3泛型函數,這是最自然的接口。

完整的當前代碼位於https://gist.github.com/friendly/749b5a69a067e02b87dd 我可以將其全部粘貼到此處,但是也許該鏈接就足夠了。

我不了解訪問模型對象組件的函數中使用的很多魔術。 我將在leveneTest中的car包裝中找到的代碼用作模板,它解決了單變量模型的類似問題。

這是使用默認方法boxM.default的快速測試:

data(iris)
res <- boxM(iris[, 1:4], iris[, "Species"])
res

這給出了預期的結果:

>     data(iris)
>     res <- boxM(iris[, 1:4], iris[, "Species"])
>     res

        Box's M-test for Homogeneity of Covariance Matrices

data:  iris[, 1:4]
Chi-Sq (approx.) = 140.94, df = 20, p-value < 2.2e-16
> 

當我嘗試直接調用公式方法boxM.formula ,它也起作用,給出與上述相同的輸出。

boxM( cbind(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width) ~ Species, data=iris)

但是,對boxM.lm方法的測試失敗:

> iris.mod <- lm(cbind(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width) ~ Species, data=iris)
> boxM(iris.mod)
Error in cbind(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width) : 
  object 'Sepal.Length' not found
> traceback()
8: cbind(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width)
7: eval(expr, envir, enclos)
6: eval(predvars, data, env)
5: model.frame.default(form, data)
4: model.frame(form, data) at boxM.R#59
3: boxM.formula(formula(y), data = model.frame(y), ...) at boxM.R#76
2: boxM.lm(iris.mod) at boxM.R#2
1: boxM(iris.mod)
>

我想我理解為什么會失敗---與在model.frame()查找變量的環境有關,但與如何糾正它無關。

有人可以幫忙嗎?

您設計的boxM函數可以將lm對象作為輸入。 該實現嘗試從lm提取公式和model.frame並與boxM.formula一起使用。

似乎model.frame(iris.mod)此問題的原因是因為model.frame(iris.mod)不會返回原始data.frame而是返回一個兩列data.frame,其中第一列包含左側變量矩陣,第二個是右側的向量 您可以通過以下方式檢查

class(model.frame(iris.mod))
dim(model.frame(iris.mod))
names(model.frame(iris.mod))
model.frame(iris.mod)[,1]
model.frame(iris.mod)[,2]

由於model.frame(iris.mod)已將數據解析為可計算格式, boxM.formula當輸入lm對象時,可以應用boxM.default而不是boxM.formula 例如,這似乎起作用:

boxM.default(Y = model.frame(iris.mod)[,1], 
             group = model.frame(iris.mod)[,2])

#    Box's M-test for Homogeneity of Covariance Matrices

#data:  model.frame(iris.mod)[, 1]
#Chi-Sq (approx.) = 140.94, df = 20, p-value < 2.2e-16

解決此問題的同事說:“您被不規范的評估所咬。”

這是一個可行的解決方案,並且更普遍地符合模型對象的S3方法。 它在模型公式的環境中查找data

boxM.lm <- function(y, ...) {
  data <- getCall(y)$data
  y <- if (!is.null(data)) {
    data <- eval(data, envir = environment(formula(y)))
    update(y, formula(y), data = data)
  }
  else update(y, formula(y))

  boxM.formula(formula(y), data=eval(data, envir = environment(formula(y))), ...)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM