2

当变量引用为".$mpg".

读完这里之后,我认为使用 as.name 就可以了,因为我有一个字符串,它给出了一个变量名。

例如,这有效:

mtcars %>% 
summarise_(interp(~mean(var), var = as.name("mpg")))

这不起作用:

mtcars %>% 
summarise_(interp(~mean(var), var = as.name(".$mpg")))

但这确实:

mtcars %>% 
 summarise(mean(.$mpg)) 

这也是:

mtcars %>%
summarise(mean(mpg)) 

我希望能够在表单中指定变量,.$mpg以便当我没有为数据指定点的选项时可以将它与 do() 一起使用,如下例所示:

library(dplyr)
library(broom)

mtcars %>% 
 tbl_df() %>% 
 slice(., 1) %>% 
 do(tidy(prop.test(.$mpg, .$disp, p = .50)))
  • 这里选择了随机变量来演示 prop.test 函数是如何工作的,请不要将此解释为滥用测试。

最终,我想把它变成这样的函数:

 library(lazyeval)
 library(broom)
 library(dplyr)


p_test <- function(x, miles, distance){
        x %>% 
         tbl_df() %>% 
         slice(., 1) %>% 
         do_(tidy(prop.test(miles, distance, p = .50))) 
  }

p_test(mtcars, ".$mpg", ".$disp")

我最初认为我必须做类似的事情: interp(~var, var = as.name(miles)wheremiles将被替换为.$mpg,但正如我在顶部提到的那样,这似乎不起作用。

4

1 回答 1

1

原因是它as.name创建了一个未计算的变量名,但是.$mpg,当在代码中使用时,它不是一个变量名。相反,它是一个复杂的表达式,相当于:

`$`(., mpg)

也就是说,它是对$带有两个参数的函数的函数调用。Usingas.name导致 R 随后搜索具有该名称的变量,`.$mpg`而不是调用上述函数。

这就是为什么您的尝试不起作用的解释。解决方案相对简单:我们需要创建一个未计算的函数调用表达式,而不是创建一个未计算的变量名。我们可以通过多种方式做到这一点,我将在这里展示两种。

首先是简单地调用parse

p_test = function (data, miles, distance) {
    x = parse(text = miles)[[1]]
    n = parse(text = distance)[[1]]
    data %>%
        slice(1) %>%
        do_(interp(~tidy(prop.test(x, n, p = 0.5)), x = x, n = n))
}

现在您可以调用p_test(mtcars, '.$mpg', '.$disp')并获得所需的结果。

但是,做同样事情的更dplyrp_test -y 方式是将未评估的对象传递给:

p_test(mtcars, mpg, disp)

......我们可以通过简单的更改轻松做到这一点:

p_test_ = function (data, var1, var2) {
    data %>%
        slice(1) %>%
        do_(interp(~tidy(prop.test(.$x, .$n, p = 0.5)),
                   x = as.name(var1), n = as.name(var2)))
}

p_test = function (data, var1, var2) {
    p_test_(data, substitute(var1), substitute(var2))
}

现在以下两段代码都可以工作:

p_test(mtcars, mpg, disp)
p_test_(mtcars, 'mpg', 'disp')
于 2016-03-23T11:00:36.540 回答