【问题标题】:Right Way to Replace Names by Strings in Expressions在表达式中用字符串替换名称的正确方法
【发布时间】:2026-02-05 11:10:02
【问题描述】:

我有一些关于在不同函数中以一致的方式用字符串替换表达式中的名称的问题 来自数据框

sample_df <- data.frame(a = 1:5, b = 5:1, c = c(5, 3, 1, 4, 1))
  • lm 中,我可以使用不同的命令将回归量替换为公式中的字符串

    lm(a~get("b"),sample_df) # substituting a part of a formula
    lm(a~eval(as.name("b")),sample_df) # substituting a part of a formula
    lm(substitute(a~v,list(v=as.name("b"))),sample_df) # substituting the whole formula
    lm(eval(substitute(a~v,list(v=as.name("b"))),sample_df)) # substituting the whole formula
    eval(substitute(lm(a~v,sample_df),list(v=as.name("b")))) # substituting the whole call
    

    所有这些命令之间有什么区别?我可以看到前两个命令给出了一个分别命名为 get("b")eval(as.name("b")) 的回归量,而其他命令给出了 b。还有其他(可能更微妙/有问题的)差异吗?为什么eval 在 3 和 4 之间不相关?

  • data.table 中,所有工作都类似于lm

    sample_dt=as.data.table(sample_df)
    sample_dt[,mean:=mean(get("b"))]
    sample_dt[,eval(substitute(mean:=mean(v),list(v=as.name("b"))))]
    eval(substitute( sample_dt[,mean:=mean(v)],list(v=as.name("b"))))
    
  • 现在,尝试用 dplyr 中的字符串替换名称

    sample_df %>% mutate(mean=mean(get("b")))
    eval(substitute(sample_df %>% mutate(mean=mean(v)),list(v=as.name("b"))))
    

    第一个在全局环境中寻找一个对象,而第二个工作。我怎么能预测 getlm[.data.table 中工作时不会在这里工作?

【问题讨论】:

  • 为什么不lm(a~b,sample.df) ?这就是帮助页面上的建议。
  • 啊哈。当提出最简单的例子时,总是同样的问题。我真的想用一个字符串代替 - 假设我想使用它们的名字循环不同的回归器。
  • 所以你要做类似 (for x in c("b","c")) lm(a~as.name(x),data.frame)` 的事情?另外,您想要一个“好”的输出名称用于predict.lm 之类的东西?
  • 无论我是否直接使用 b 而不是“b”,我都想要完全相同的输出。假设我想将我经常做的事情重写为以数据框和变量名作为参数的函数。

标签: r expression dplyr lm


【解决方案1】:

您为所描述的目的错误地设置了测试用例。您想通过包含字符值的变量传入各种值:

sample_df <- data.frame(a = 1:5, b = 5:1, c = c(5, 3, 1, 4, 1))
x <- "b"
lm(a~get(x),sample_df) # succeeds
lm(a~eval(as.name(x)),sample_df)  # also succeeds

更典型的做法是在 lm() 调用之外使用 as.formula:

form <- as.formula(paste("a ~", x))
form
#a ~ b
lm(form,sample_df)
predict(lm(form,sample_df))
1 2 3 4 5 
1 2 3 4 5 

在 lm() 函数之外执行此操作的优点是替换在 lm 处理工具记录调用之前完成。比较输出:

terms(lm(form,sample_df))
terms( lm(a~eval(as.name(x)),sample_df))

从第二个示例返回到quote(b) 需要大量的“语言计算”,而如果传入公式对象,则很容易从 terms() 对象中获取 RHS:

> terms(lm(form,sample_df))[[3]]
b

【讨论】:

  • 我明白你的意思。但是,如果我想替换一个 not 公式的表达式,比如在 data.table 或 dplyr 中,该怎么办? deparse 真的是要走的路吗?
  • 首先要做的是将您的术语采用符合 R 用法的形式,以便我们可以进行明确的讨论。目前我无法说出你的提议。在 R 中,表达式不是公式,公式也不是表达式。
  • 然后我问如何在公式和表达式中以一致的方式使用您的方法 - 在我的示例中为 lm(v2~v1,DT)DT[,mean:=mean(v1)]
  • 这个问题似乎无法集中注意力。我无法弄清楚您正在检查哪种评估环境。这是解决您不确定性的 dplyr 部分的问题/答案:*.com/questions/22005419/… 吗?
  • 这正是我在dplyr(第二个命令)中所做的。此解决方案适用于 lm data.tabledplyr 中的所有示例。