如果不调用polym(),我如何计算它将返回的交互次数?

时间:2017-05-04 03:45:16

标签: r polynomials

如何计算poly将返回的互动次数?

如果我有两个变量,那么将以度数函数返回的互动poly的数量由下式给出:

degree <- 2

dim(poly(rnorm(10), rnorm(10), degree = degree))[2]

这与:

相同
(degree^2+3*degree)/2

无论如何,根据学位和变量的数量来计算相互作用的数量(如果我使用两个以上)?

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提供从1D的每个学位的互动次数,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来计算所有可用交互的程度。最后,应用了一个过滤器,仅保留1D之间的互动度。

答案 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