Ответ 1
Я вижу пару вопросов, которые здесь происходят. Во-первых, и я не думаю, что это вызывает какие-либо проблемы, но позвольте сделать ваш кадр данных за один шаг, чтобы у вас не было v1
через v4
, плавающего как в глобальной среде, так и в кадре данных, Во-вторых, позвольте просто сделать v2
фактором здесь, чтобы нам не пришлось иметь дело с тем, чтобы сделать его фактором позже.
dat <- data.frame(v1 = rnorm(10),
v2 = factor(sample(c(0,1), 10, replace=TRUE)),
v3 = rnorm(10),
v4 = rnorm(10) )
Часть первая Теперь, для вашей первой части, похоже, это то, что вы хотите:
lm(v1 ~ v2 + v3 + v4, data=dat)
Здесь более простой способ сделать это, хотя вам все равно нужно указать переменную ответа.
lm(v1 ~ ., data=dat)
В качестве альтернативы вы можете создать функцию с пастой и вызвать lm
на ней.
f <- paste(names(dat)[1], "~", paste(names(dat)[-1], collapse=" + "))
# "v1 ~ v2 + v3 + v4"
lm(f, data=dat)
Однако в этих ситуациях я предпочитаю использовать do.call
, который вычисляет выражения перед передачей их функции; это делает результирующий объект более подходящим для вызова функций типа update
on. Сравните call
часть вывода.
do.call("lm", list(as.formula(f), data=as.name("dat")))
Часть вторая О вашей второй части, похоже, вот что вы собираетесь делать:
lm(factor(v2) + v3 + v4 + v2*v3 + v2*v4, data=dat)
Во-первых, поскольку v2
является фактором в кадре данных, нам эта часть не нужна, и, во-вторых, это может быть упрощено дальше, используя методы R для использования арифметических операций для создания взаимодействий, например.
lm(v1 ~ v2*(v3 + v4), data=dat)
Я бы просто создал функцию, используя paste
; цикл с assign
, даже в большем случае, вероятно, не очень хорошая идея.
f <- paste(names(dat)[1], "~", names(dat)[2], "* (",
paste(names(dat)[-c(1:2)], collapse=" + "), ")")
# "v1 ~ v2 * ( v3 + v4 )"
Затем его можно вызвать с помощью либо lm
напрямую, либо с помощью do.call
.
lm(f, data=dat)
do.call("lm", list(as.formula(f), data=as.name("dat")))
О вашем коде Проблема, с которой вы пытались использовать r3
и т.д., заключалась в том, что вам нужно содержимое переменной r3
, а не значение r3
. Чтобы получить значение, вам нужно get
, как это, а затем вы сбрасываете значения вместе с paste
.
vars <- sapply(paste0("r", 3:6), get)
paste(vars, collapse=" + ")
Однако лучшим способом было бы избежать assign
и просто построить вектор терминов, которые вы хотите, например.
vars <- NULL
for (v in 3:4) {
vars <- c(vars, colnames(dat)[v], paste(colnames(dat)[2],
colnames(dat)[v], sep="*"))
}
paste(vars, collapse=" + ")
Более R-образное решение было бы использовать lapply
:
vars <- unlist(lapply(colnames(dat)[3:4],
function(x) c(x, paste(colnames(dat)[2], x, sep="*"))))