class_docstr: a wrapper class for two way anova type of analysis with OLS
  
  
  currently mainly to bring things together
  
  Notes
  -----
  unclear: adding multiple test might assume block design or orthogonality
  
  This estimates the full dummy version with OLS.
  The drop first dummy representation can be recovered through the
  transform method.
  
  TODO: add more methods, tests, pairwise, multiple, marginal effects
  try out what can be added for userfriendly access.
  
  missing: ANOVA table
class_docstr_tok: ["a","wrapper","class","for","two","way","anova","type","of","analysis","with","OLS","currently","mainly","to","bring","things","together","Notes","--","--","-","unclear",":","adding","multiple","test","might","assume","block","design","or","orthogonality","This","estimates","the","full","dummy","version","with","OLS",".","The","drop","first","dummy","representation","can","be","recovered","through","the","transform","method",".","TODO",":","add","more","methods",",","tests",",","pairwise",",","multiple",",","marginal","effects","try","out","what","can","be","added","for","userfriendly","access",".","missing",":","ANOVA","table"]
code: def __init__(self, endog, factor1, factor2, varnames=None):
      self.nobs = factor1.shape[0]
      if varnames is None:
          vname1 = "a"
          vname2 = "b"
      else:
          vname1, vname1 = varnames
  
      self.d1, self.d1_labels = d1, d1_labels = dummy_1d(
          factor1, vname1
      )
      self.d2, self.d2_labels = d2, d2_labels = dummy_1d(
          factor2, vname2
      )
      self.nlevel1 = nlevel1 = d1.shape[1]
      self.nlevel2 = nlevel2 = d2.shape[1]
  
      # get product dummies
      res = contrast_product(d1_labels, d2_labels)
      prodlab, C1, C1lab, C2, C2lab, _ = res
      (
          self.prod_label,
          self.C1,
          self.C1_label,
          self.C2,
          self.C2_label,
          _,
      ) = res
      dp_full = dummy_product(d1, d2, method="full")
      dp_dropf = dummy_product(d1, d2, method="drop-first")
      self.transform = DummyTransform(dp_full, dp_dropf)
  
      # estimate the model
      self.nvars = dp_full.shape[1]
      self.exog = dp_full
      self.resols = sm.OLS(endog, dp_full).fit()
      self.params = self.resols.params
  
      # get transformed parameters, (constant, main, interaction effect)
      self.params_dropf = self.transform.inv_dot_left(self.params)
      self.start_interaction = 1 + (nlevel1 - 1) + (nlevel2 - 1)
      self.n_interaction = self.nvars - self.start_interaction
  
imports: from numpy.testing import assert_equal
  import numpy
label_desc: Use image node_id 1 to create a new TwoWay object  with example: obj = TwoWay(endog, factor1, factor2, varnames)