用表达式中的字符串替换名称的正确方法

时间:2014-09-14 15:55:39

标签: r expression dplyr lm

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

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工作时无效?

1 个答案:

答案 0 :(得分:3)

为了描述的目的,您正在错误地设置测试用例。您希望使用包含字符值的变量传递各种值:

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)需要很多体操“语言计算”,而如果公式对象通过则很容易从术语() - 对象中获取RHS在:

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