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

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

Updated below code

# 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)

更新:

这里有一个不起作用的例子:)使用上面创建的相同数据帧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)

推荐答案

我看到这里有几个问题.首先,我不认为这会造成任何问题,但让我们一步完成数据帧,这样在全球环境和数据帧中都不会有v1v4的浮动.第二,让我们把v2作为一个因子,这样我们以后就不必把它作为一个因子了.

dat <- data.frame(v1 = rnorm(10),
                  v2 = factor(sample(c(0,1), 10, replace=TRUE)),
                  v3 = rnorm(10),
                  v4 = rnorm(10) )

Part One现在,对于你的第一部分,看起来这就是你想要的:

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

这里有一个更简单的方法来实现这一点,尽管您仍然需要指定response变量.

lm(v1 ~ ., data=dat)

或者,您当然可以使用paste构建函数,并在其上调用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")))

Part Two关于你的第二部分,看起来这就是你想要的:

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")))

About your codetry 使用r3 etc时遇到的问题是,您想要的是变量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="*"))))

R相关问答推荐

在R中,如何创建时间间隔的图表?

在R中使用自定义函数时如何删除该函数的一部分?

将模拟变量乘以多个观测结果中的模拟变量

如何使用R Shiny中的条件面板仅隐藏和显示用户输入,同时仍允许运行基础计算?

咕噜中的元素列表:map

用derrr在R中查找组间的重复项

有没有一个R函数允许你从一个数字变量中提取一个数字,而不考虑它的位置(不仅仅是第一个或最后一个数字?

更改默认系列1以更改名称

如何通过Docker部署我的shiny 应用程序(多个文件)

将数据集中的值增加到当前包含的最大值

如何提取所有完美匹配的10个核苷酸在一个成对的匹配与生物字符串在R?>

Data.table';S GForce-将多个函数应用于多列(带可选参数)

R中有约束的优化问题:如何用复数和对数效益函数解决问题?

R:用GGPLATE,如何在两个独立的变量中制作不同形状的散点图?

计算直线上点到参考点的总距离

按组计算列中1出现的间隔年数

如何计算R glm probit中的线性预测因子?

有没有办法定制Plot(allEffects())面板标题?

注释不会绘制在所有ggplot2面上

R-使用stri_trans_General()将其音译为德语字母