There was a warning (not an error) because in the question dependent_var has more than one element and it is letting you know it is ignoring all but the first element. Also note that you don't have to convert the string to a formula as lm will accept a character string but if given a character vector of length > 1 it will ignore all but the first element and give a similar warning.
We can modify the code in the question to this:
paste(sprintf("cbind(%s)", toString(dependent_var)), "~",
paste(var_names, collapse = " + "))
giving:
[1] "cbind(PC_1_mets_men, PC_2_mets_men, PC_3_mets_men) ~ PC_1_food_men + covar_prev_diab"
however, using reformulate as in the next section is a bit easier.
reformulate
Instead, we can form the LHS using sprintf and then use that with the independent variables in reformulate. Using the built in CO2 data set so that we can actually run the result:
dep_vars <- names(CO2)[4:5] # c("conc", "uptake")
indep_vars <- names(CO2)[2:3] # c("Type", "Treatment")
fo <- reformulate(indep_vars, sprintf("cbind(%s)", toString(dep_vars)))
fo
## cbind(conc, uptake) ~ Type + Treatment
lm(fo, CO2)
giving:
Call:
lm(formula = fo, data = CO2)
Coefficients:
conc uptake
(Intercept) 4.350e+02 3.697e+01
TypeMississippi -5.582e-14 -1.266e+01
Treatmentchilled 0.000e+00 -6.860e+00
The question had multiple dependent variables but if there were only one then we could simplify the reformulate statement. For example, to only use the first dependent variable:
reformulate(indep_vars, dep_vars[1])
## conc ~ Type + Treatment
Nicer looking Call line
The Call: line above shows the RHS as literally fo but we can use do.call to force it to produce a nicer looking Call: line.
do.call("lm", list(fo, quote(CO2)))
giving:
Call:
lm(formula = cbind(conc, uptake) ~ Type + Treatment, data = CO2)
Coefficients:
conc uptake
(Intercept) 4.350e+02 3.697e+01
TypeMississippi -5.582e-14 -1.266e+01
Treatmentchilled 0.000e+00 -6.860e+00