【问题标题】:Flexible comparison of formula equivalence in R?R中公式等价的灵活比较?
【发布时间】:2019-08-09 17:54:00
【问题描述】:

考虑这些具有交互作用的各种 R 公式:

x ~ a + b + c + d + c:d + a:b
x ~ c + a + b + d + a:b + d:c
x ~ a + b + c + d + c * d + a * b
x ~ a * b + c * d
x ~ b * a + c * d

出于线性模型之类的目的,这些都是等价的。假设我有一大套公式,我想比较是否有任何重复,但可能有像上面这样不明显的重复。有没有一种简单的方法来进行这种比较?

共有三个挑战:

  • 必须删除冗余(d + c * d 等价于 c * d)
  • 必须能够以不同的顺序匹配元素(a + b 与 b + a 相同)
  • 必须能够匹配通勤交互(c:d 与 d:c 相同)

只是一个带有一些排序的 terms() 调用似乎没有得到它,主要是因为最后一个。

这是我到目前为止的工作方式(写成functional sequence 以便于阅读):

# uses tidyverse

get.terms <- {
  . %>%              
    terms %>%                  # use terms to get the parts
    attr("term.labels") %>%    # character vector of elements
    str_split(":") %>%         # separate interaction terms (makes list)                        
    map_chr(                   # go through each list item
      ~.x %>% 
      sort %>%                 # if multiples (interaction), sort
      paste0(collapse = ":")   # combine back 
    ) %>%                      # output (now standardized) term list
    sort                       # sort the term list for comparison
  }

# Which gives:
get.terms(x ~ a + b + c + d + c:d + a:b)
get.terms(x ~ c + a + b + d + a:b + d:c)
get.terms(x ~ a + b + c + d + c * d + a * b)
get.terms(x ~ a * b + c * d)
get.terms(x ~ b * a + c * d)

# so you can test:
all.equal(get.terms(x ~ b * a + c * d), get.terms(x ~ c + a + b + d + a:b + d:c))

# would have to add more for this, though:
all.equal(get.terms(foo ~ b * a + c * d), get.terms(bar ~ c + a + b + d + a:b + d:c))

但是对于 R 的这样一个基本部分来说,这似乎是 hacky。

我意识到你可能会在接近尾声时通过列表元素比较来缩短这一点,但额外的步骤是有意的,因为这个想法也是为了能够构建一个标准化的人类可读的公式表示法。更何况整个过程,尤其是交互术语的翻转,似乎没有必要

有人知道更简单或更规范的方法吗?

如果它还可以包含潜在的左侧差异,则可以加分。

如果它可以输出标准化的公式格式(或等效的字符串),则加倍奖励。

【问题讨论】:

标签: r comparison formula equivalent


【解决方案1】:

我想知道这个想法是否可以扩展到更一般的东西。

frm1 <- x ~ a + b + c + d + c:d + a:b
frm2 <- x ~ c + a + b + d + a:b + d:c

identical(
  sort(attr(terms.formula(frm1), "term.labels")),
  sort(attr(terms.formula(frm2), "term.labels"))
)

[1] TRUE

【讨论】:

  • 上述frm1frm5 的想法将失败。需要strsplit,这并不难编码。
  • 啊哈。 d:c 重新排列为 c:d,因为 cd 之前已出现在公式中。
  • 这作为术语列表按交互术语显示的顺序排列,它们最初作为主要效果的呈现方式。在您的两个示例中,c 都在 d 之前。但是,如果这些被切换,它并不能一概而论。考虑这两个额外的公式:frm3 &lt;- x ~ a + b + d + a:b + d*cfrm4 &lt;- x ~ a + b + d + c + a:b + d:c。 (抱歉,没有刷新看到上面的 cmets 进来。)
  • Rui,strsplit 基本上不是我最初提出的吗? (仅使用 stringr 版本)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-19
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
  • 2013-11-18
相关资源
最近更新 更多