如何通过公式中的string使用引用variables?

在下面的最简单的例子中,我试图在回归公式中使用stringvars的值。 但是,我只能将这个string的variables名称(“v2 + v3 + v4”)传递给公式,而不是这个string的真正含义(例如“v2”是dat $ v2)。

我知道有更好的方法来运行回归(例如, lm(v1 ~ v2 + v3 + v4, data=dat) )。 我的情况更复杂,我想弄清楚如何在公式中使用string。 有什么想法吗?

更新下面的代码

 # minimal example # create data frame v1 <- rnorm(10) v2 <- sample(c(0,1), 10, replace=TRUE) v3 <- rnorm(10) v4 <- rnorm(10) dat <- cbind(v1, v2, v3, v4) dat <- as.data.frame(dat) # create objects of column names c.2 <- colnames(dat)[2] c.3 <- colnames(dat)[3] c.4 <- colnames(dat)[4] # shortcut to get to the type of object my full code produces vars <- paste(c.2, c.3, c.4, sep="+") ### TRYING TO SOLVE FROM THIS POINT: print(vars) # [1] "v2+v3+v4" # use vars in regression regression <- paste0("v1", " ~ ", vars) m1 <- lm(as.formula(regression), data=dat) 

更新:在第一个例子中,@Arun对于v1上缺less的“”是正确的。 这固定我的例子,但我仍然有我的真实代码的问题。 在下面的代码块中,我调整了我的示例以更好地反映我的实际代码。 我首先想到创build一个更简单的例子,认为问题是stringvars

这是一个不起作用的例子:)使用上面创build的相同的dataframedat

 dv <- colnames(dat)[1] r2 <- colnames(dat)[2] # the following loop creates objects r3, r4, r5, and r6 # r5 and r6 are interaction terms for (v in 3:4) { r <- colnames(dat)[v] assign(paste("r",v,sep=""),r) r <- paste(colnames(dat)[2], colnames(dat)[v], sep="*") assign(paste("r",v+2,sep=""),r) } # combine r3, r4, r5, and r6 then collapse and remove trailing + vars2 <- sapply(3:6, function(i) { paste0("r", i, "+") }) vars2 <- paste(vars2, collapse = '') vars2 <- substr(vars2, 1, nchar(vars2)-1) # concatenate dv, r2 (as a factor), and vars into `eq` eq <- paste0(dv, " ~ factor(",r2,") +", vars2) 

这是问题:

 print(eq) # [1] "v1 ~ factor(v2) +r3+r4+r5+r6" 

与第一个例子中的regression不同, eq没有列出列名(例如, v3 )。 对象名称(例如, r3 )被保留。 因此,下面的lm()命令不起作用。

 m2 <- lm(as.formula(eq), data=dat) 

我在这里看到一些问题。 首先,我认为这不会造成任何麻烦,但是让我们一步一步地完成数据框架,这样您就不必在全局环境和数据框架中都有v1v4浮动。 其次,让我们把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) 

下面是一个简单的方法来做到这一点,但你仍然需要指定响应variables。

 lm(v1 ~ ., data=dat) 

另外,你也可以通过粘贴来build立函数,并调用lm函数。

 f <- paste(names(dat)[1], "~", paste(names(dat)[-1], collapse=" + ")) # "v1 ~ v2 + v3 + v4" lm(f, data=dat) 

但是,在这些情况下,我喜欢使用do.call ,它在将expression式传递给函数之前对其进行求值。 这使得生成的对象更适合调用update等function。 比较输出的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的方法来使用算术运算来创build交互,这可以进一步简化。

 lm(v1 ~ v2*(v3 + v4), data=dat) 

然后我只需使用paste创build函数; 即使在更大的情况下, 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等的问题是你想要variablesr3的内容,而不是r3的值。 为了获得价值,你需要像这样get ,然后你会用paste的价值。

 vars <- sapply(paste0("r", 3:6), get) paste(vars, collapse=" + ") 

然而,更好的方法是避免assign ,只是build立你想要的术语向量,就像这样。

 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的解决scheme将是使用lapply

 vars <- unlist(lapply(colnames(dat)[3:4], function(x) c(x, paste(colnames(dat)[2], x, sep="*")))) 

TL; DR:使用paste

 create_ctree <- function(col){ myFormula <- paste(col, "~.", collapse="") ctree(myFormula, data) } create_ctree("class")