2014-11-12 1 views
5

У меня есть модель с преобразованных переменных, например:Удалить переменную, завернутые в функции от модельной формулы в R

data = data.frame(y = runif(100,0,10), x1 = runif(100,0,10), x2 = runif(100, 0, 10)) 
mod = lm(y ~ scale(x1) + scale(x2), data) 

Я хотел бы удалить одну целую переменную из формулы, например, так:

mod = lm(y ~ scale(x1), # x2 is gone! 
data) 

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

Если переменная был нетрансформированным, это было бы просто с помощью gsub:

remove.var = "x2" 
update(mod, formula. = as.formula(gsub(remove.var, "", format(formula(mod))))) 

но как таковые, он возвращает полностью предсказуемую ошибку:

> Error in as.matrix(x) : argument "x" is missing, with no default 

потому что scale() все еще в формуле!

Есть ли способ сделать это с помощью regexpr, или каким-то образом, который я не вижу, это совершенно очевидно? Я бы хотел, чтобы он был масштабируемым для других типов преобразований, например: log, log10 и т. Д.

В качестве другого слоя сложности, предположим, что переменная быть удалены также появилась во взаимодействии:

mod = lm(y ~ scale(x1) * scale(x2), data) 

В этом случае можно было бы удалить взаимодействие * а (странствующих + S, I нашли, все в порядке).

Любая помощь очень ценится. Благодаря!

+0

Это вид кажется, что вы собираетесь это в обратном направлении. Как вы строите формулу в первую очередь? Попытка удалить детали (или функции частей или взаимодействия с частями) может быть довольно сложной после факта. Похоже, вы должны просто построить формулу на основе пользовательского ввода напрямую. – MrFlick

ответ

3

Условий-объект является формула с дополнительными атрибутами:

update(mod, formula=drop.terms(mod$terms, 2, keep.response=TRUE) ) 

Call: 
lm(formula = y ~ scale(x1), data = data) 

Coefficients: 
(Intercept) scale(x1) 
    5.0121  0.1236 

Если вам нужно вычислить эту позицию из аргумента строки, то вы можете вычленить атрибут term.labels:

> grep("x2", attr(mod$terms, "term.labels")) 
[1] 2 

Обратите внимание, что это также преуспевает с формулой взаимодействия:

update(mod, formula=drop.terms(mod$terms, grep("x2", attr(mod$terms, "term.labels")), keep.response=TRUE)) 
#---------- 

Call: 
lm(formula = y ~ scale(x1), data = data) 

Coefficients: 
(Intercept) scale(x1) 
    5.0121  0.1236 
+0

Блестящий, спасибо! – jslefche

0

Я уверен, Re другой способ сделать это с caret пакет, но я думаю, что это делает то, что вы хотите:

vars<- c("tom", "dick", "harry") 
remove<- "tom" 
vars<- setdiff(vars, remove) 

formula <- as.formula(paste("y ~", paste("scale(", vars, ")", collapse = "+"))) 
Смежные вопросы