如何计算poly
将返回的互动次数?
如果我有两个变量,那么将以度数函数返回的互动poly
的数量由下式给出:
degree <- 2
dim(poly(rnorm(10), rnorm(10), degree = degree))[2]
这与:
相同(degree^2+3*degree)/2
无论如何,根据学位和变量的数量来计算相互作用的数量(如果我使用两个以上)?
答案 0 :(得分:2)
组合的数学结果
假设您有p
个变量,与度d
相关联的互动次数由下式计算:
fd <- function (p, d) {
k <- choose(p, d)
if (d > 1) k <- k + p * sum(choose(p-1, 0:(d-2)))
return(k)
}
函数poly
(在这种情况下实际为polym
),p
输入变量和degree = D
,将构建从degree = 1
到{degree = D
的交互{1}}。所以以下函数计算它:
fD <- function (p, D) {
if (D < 1) return(0)
component <- sapply(1:D, fd, p = p)
list(component = component, ncol = sum(component))
}
条目component
提供从1
到D
的每个学位的互动次数,ncol
组件提供互动的总次数。
快速测试:
a <- runif(50)
b <- runif(50)
c <- runif(50)
d <- runif(50)
X <- poly(a, b, c, d, degree = 3)
ncol(X)
# 34
fD(4, 3)
# component
# [1] 4 10 20
#
# ncol
# [1] 34
R如何做到这一点?
polym
源代码的前几行解释了R如何解决这个问题。首先调用expand.grid
以获取所有可能的交互,然后调用rowSums
来计算所有可用交互的程度。最后,应用了一个过滤器,仅保留1
和D
之间的互动度。
答案 1 :(得分:0)
三年多以后,我不得不处理> = 3的多项式。不幸的是,@李哲源的解决方案在度数大于3时失败。但是,我可以建立两个解决方案:
扩展网格解决方案
此方法模拟polym
的原始行为,这对于我们的目的而言不是很优雅,但是是自然的基准。
expand_grid_solution <- function(nd, degree){
z <- do.call(expand.grid, c(rep.int(list(0:degree), nd),
KEEP.OUT.ATTRS = FALSE))
s <- rowSums(z)
ind <- 0 < s & s <= degree
z <- z[ind, , drop = FALSE]
s <- s[ind]
return(length(s))
}
与重复解决方案组合
combination_with_repetition <- function(n, r){
factorial(r+n-1)/(factorial(n-1)*factorial(r))
}
poly_elements <- function(n, d) {
x <- sapply(1:d, combination_with_repetition, n = n)
return(sum(x))
}
快速测试:
mapply(expand_grid_solution, c(2,2,2,3,3,3,4), c(2,3,4,2,3,4,4))
#[1] 5 9 14 9 19 34 69
mapply(poly_elements, c(2,2,2,3,3,3,4), c(2,3,4,2,3,4,4))
#[1] 5 9 14 9 19 34 69