我们可以不将管链输出传递到线性模型 lm() 点占位符吗?

问题描述

我想知道如何将管道操作的输出直接传递给lm()

例如,我可以将以下 yay 向量直接传递给 lm()

set.seed(40)
yay = c(rnorm(15),exp(rnorm(15)),runif(20,min = -3,max = 0))
lm(yay~1)

#> Call:
#> lm(formula = yay ~ 1)

#> Coefficients:
#> (Intercept)  
#>    -0.09522  

但是当我尝试这样的事情时,它抛出了一个错误

library(tidyverse)
library(palmerpenguins)

data("penguins")

filter_penguins <- penguins %>% filter(species == "Adelie") 

filter_penguins %>% 
  filter(island == "Torgersen") %>% 
  select(bill_length_mm) %>%
  pull() %>% 
  lm(. ~ 1)

#> Error in formula.default(object,env = baseenv()) : invalid formula

我还尝试将 pull() 输出保存到对象中,然后将其输入 lm(),它可以工作。但是为什么点占位符不能这样工作?

非常感谢。

解决方法

这个问题是管道内的 lm() 考虑作为 formula 参数给出的数据。因此,数据错位。试试:

filter_penguins %>% 
  filter(island == "Torgersen") %>% 
  select(bill_length_mm) %>%
  lm(data = .,pull(.) ~ 1)
,

编辑:我意识到我误读了这个问题,并认为 OP 想要将变量名称作为公式的一部分传入,而不是传入数据集本身。无论如何,我会出于前一个原因保留这篇文章。

它不起作用,因为 lm 的第一个参数将是管道输入的任何内容,这不是一个正确的公式(如错误所示)。

使用您的示例,并假设管道值为“var”,然后

"var" %>% 
    lm(. ~ 1)

将被评估为

lm(formula = "var",. ~ 1)

所以 . ~ 1 部分不是公式参数的一部分。不过,您可以使用 paste0 或类似方法构建公式。例如,这将起作用:

"mpg" %>%
    paste0(" ~ .") %>%
    lm(data = mtcars)