Поиск списка формул в другом списке - PullRequest
0 голосов
/ 19 февраля 2019

Я сравниваю два списка формул, чтобы увидеть, можно ли повторно использовать некоторые ранее вычисленные модели.Прямо сейчас я делаю это так:

set.seed(123)

# create some random formulas
l1 <- l2 <- list()
for (i in 1:10) {
  l1[[i]] <- as.formula(paste("z ~", paste(sample(letters, 3), collapse = " + ")))
  l2[[i]] <- as.formula(paste("z ~", paste(sample(letters, 3), collapse = " + ")))
}
# at least one appears in the other list
l1[[5]] <- l2[[7]]

# helper function to convert formulas to character strings
as.formulaCharacter <- function(x) paste(deparse(x))

# convert both lists to strings
s1 <- sapply(l1, as.formulaCharacter)
s2 <- sapply(l2, as.formulaCharacter)

# look up elements of one vector in the other
idx <- match(s1, s2, nomatch = 0L) # 7
s1[idx] # found matching elements

Однако я заметил, что некоторые формулы не извлекаются, хотя они практически эквивалентны.

f1 <- z ~ b + c + b:c
f2 <- z ~ c + b + c:b

match(as.formulaCharacter(f1), as.formulaCharacter(f2)) # no match

Я понимаю, почему этот результатразные строки просто не одинаковы, но я борюсь с тем, как расширить этот метод подхода, чтобы он также работал с формулами с переупорядоченными элементами.Я мог бы использовать strsplit, чтобы сначала отсортировать все компоненты формулы независимо, но для меня это звучит ужасно неэффективно.

Есть идеи?

1 Ответ

0 голосов
/ 19 февраля 2019

Если формулы ограничены суммой терминов, которые содержат переменные, разделенные двоеточиями, то мы можем создать стандартизированную строку, извлекая метки терминов, разбивая те с двоеточиями, сортируя их, вставляя разорванные термины обратно вместе, сортируя это и поворачиваяэто в строку формулы.

stdize <- function(fo) {
  s <- strsplit(attr(terms(f2), "term.labels"), ":") 
  terms <- sort(sapply(lapply(s, sort), paste, collapse = ":"))
  format(reformulate(terms, all.vars(fo)[1]))
}

stdize(f1) == stdize(f2)
## [1] TRUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...