为了账号安全,请及时绑定邮箱和手机立即绑定

如何在公式中按字符串使用参考变量?

/ 猿问

如何在公式中按字符串使用参考变量?

守着一只汪 2019-11-14 15:19:03

在下面的最小示例中,我尝试vars在回归公式中使用字符串的值。但是,我只能将变量名的字符串(“ v2 + v3 + v4”)传递给公式,而不是该字符串的真实含义(例如,“ v2”是dat $ v2)。


我知道有更好的方法进行回归分析(例如lm(v1 ~ v2 + v3 + v4, data=dat))。我的情况更加复杂,我正在尝试弄清楚如何在公式中使用字符串。有什么想法吗?


更新以下代码


# 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对于第一个示例中缺少的“”是正确的。这解决了我的示例,但是我的真实代码仍然有问题。在下面的代码块中,我调整了示例以更好地反映我的实际代码。我一开始选择创建一个简单的示例,以为问题是字符串vars。


这是一个不起作用的示例:)使用dat上面创建的相同数据框。


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)


查看完整描述

2 回答

?
蝴蝶不菲

我看到这里发生了几个问题。首先,我不认为这是造成任何麻烦,但让我们一步到位您的数据帧所以你没有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,在将表达式传递给函数之前先对其求值;这使生成的对象更适合调用updateon之类的函数。比较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")))

关于您的代码尝试使用r3etc时遇到的问题是,您需要变量的内容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="*"))))


查看完整回答
反对 回复 2019-11-14
?
郎朗坤

使用paste。


create_ctree <- function(col){

    myFormula <- paste(col, "~.", collapse="")

    ctree(myFormula, data)

}

create_ctree("class")


查看完整回答
反对 回复 2019-11-14
  • 2 回答
  • 0 关注
  • 51 浏览
我要回答

相关问题推荐

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信