[英]How do you make R poly() evaluate (or "predict") multivariate new data (orthogonal or raw)?
[英]Use poly() in R formula to predict
我對公式和用戶定義函數有疑問:
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包裝為用戶定義的函數(實際上我將擁有自己更復雜的函數),那么我將得到錯誤:
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.