簡體   English   中英

使用R公式中的poly()進行預測

[英]Use poly() in R formula to predict

我對公式和用戶定義函數有疑問:

情況1:

 clotting <- data.frame(
     u = c(5,10,15,20,30,40,60,80,100),
     lot1 = c(118,58,42,35,27,25,21,19,18),
     lot2 = c(69,35,26,21,18,16,13,12,12))

 g1 = glm(lot1 ~ log(u) + poly(u,1), data = clotting, family = Gamma)
 dc = clotting
 dc$u = 1
 predict(g1, dc)

      1           2           3           4           5           6           7           8           9
 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929

但是,如果我只是簡單地將poly包裝為用戶定義的函數(實際上我將擁有自己更復雜的函數),那么我將得到錯誤:

案例2:

 xpoly <- function(x, degree=1){poly(x,degree)}
 g2 = glm(lot1 ~ log(u) + xpoly(u,1), data = clotting, family = Gamma)
 predict(g2, dc)
       Error in poly(x, degree) :
      'degree' must be less than number of unique points

似乎預測用I()處理公式中的用戶定義函數。 我的問題是如何才能得到Case2的結果與case1相同?

任何人都可以對此有任何想法?

poly在這里有點獨特的功能。 默認情況下,它返回一組正交多項式,因此它會對數據進行一些居中和重新縮放。 如果您希望能夠使用擬合模型中的系數進行預測,則需要以與原始數據相同的方式轉換新數據。 這意味着必須傳遞一些額外的數據。

首先,我要指出,如果使用原始的非正交值,則不會遇到此問題。

g1 <- glm(lot1 ~ log(u) + poly(u,1, raw=T), data = clotting, family = Gamma)
xpoly<-function(x,degree=1){poly(x,degree, raw=T)}
g2 <- glm(lot1 ~ log(u) + xpoly(u,1), data = clotting, family = Gamma)

dc=clotting
dc$u=1
predict(g1,dc)
#       1           2           3           4           5           6           7           8           9 
#-0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 
predict(g2,dc)
#       1           2           3           4           5           6           7           8           9 
#-0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929

但是讓我們進一步探討poly如何通過縮放信息進行predict 這項工作實際上發生在model.frame函數中。 比較這兩個結果

attr(terms(model.frame(lot1 ~ log(u) + poly(u,1), clotting)), "predvar")
# list(lot1, log(u), poly(u, 1, coefs = list(alpha = 40, norm2 = c(1, 
9, 8850))))
attr(terms(model.frame(lot1 ~ log(u) + xpoly(u,1), clotting)), "predvar")
# list(lot1, log(u), xpoly(u, 1))

您可以看到第一個公式中對poly()的調用已在返回的公式的predvar屬性中進行了調整。 這在model.frame代碼中完成

...
if (is.null(attr(formula, "predvars"))) {
    for (i in seq_along(varnames)) predvars[[i + 1L]] <- makepredictcall(variables[[i]], 
        vars[[i + 1L]])
    attr(formula, "predvars") <- predvars
}
...

請注意,它調用makepredictcall()函數,該函數是一個泛型函數,它根據返回對象的類進行調度。 碰巧poly返回類“poly”的對象

class(poly(1:5, 1))
# [1] "poly"   "matrix"

那么這個函數就是要求“poly”數據

stats:::makepredictcall.poly
function (var, call) 
{
    if (as.character(call)[1L] != "poly") 
        return(call)
    call$coefs <- attr(var, "coefs")
    call
}
<bytecode: 0x123262178>
<environment: namespace:stats>

這是添加coef=屬性的地方。 但另請注意,它會檢查調用是否來自“poly”函數本身。 由於您的函數名為“xpoly”但返回“poly”對象,因此不返回系數信息。 一種解決方法是更改​​對象的返回類並創建自己的makepredictcall函數。 例如,你可以做到

xpoly <- function(...){p<-poly(...); class(p)[1]<-"xpoly"; p}
makepredictcall.xpoly <- function(var, call) {
    call$coefs <- attr(var, "coefs")
    call
}

請注意,這個新版本的xpoly也將接受coef=參數,並通過...參數將其傳遞給poly() 然后你就可以跑了

g1 <- glm(lot1 ~ log(u) + poly(u,1), data = clotting, family = Gamma)
g2 <- glm(lot1 ~ log(u) + xpoly(u,1), data = clotting, family = Gamma)
predict(g1,dc)
#          1           2           3           4           5           6           7           8           9 
#-0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929
predict(g2,dc)
#          1           2           3           4           5           6           7           8           9 
#-0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929 -0.01398929

暫無
暫無

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

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