在 R 中使用函数 lm() 和 group_by

问题描述 投票:0回答:2

我正在尝试从一个数据帧为分类变量的每个级别创建一些 lm() 模型。 我将函数 lm() 与 group_by 一起使用,但它不起作用,只创建了一个模型。 当然,创建每个数据集并为每个数据集使用 lm() 很容易,但我想知道其他方式,使用 group_by、apply 等。

make_model <- function(data){
  lm(Sepal.Length~Sepal.Width,data)
}
models <- iris %>%
  group_by(Species) %>%
  make_model
predicted <- iris %>%
  group_by(Species) %>%
  mutate(prediction=predict(models,.))
r group-by apply purrr lm
2个回答
1
投票

我会查看 R 数据科学的许多模型章节: https://r4ds.had.co.nz/many-models.html

library(tidyverse)
make_model <- function(data){
  lm(Sepal.Length~Sepal.Width,data)
}

iris %>%
  group_by(Species) %>%
  nest() %>% 
  mutate(lm = map(data,
                  make_model)) %>% 
  mutate(tidy = map(lm,
                    broom::tidy)) %>% 
  unnest(tidy)

0
投票

比使用

nest()
及其所有非直观复杂性更优雅的解决方案是使用
group_modify
,它只是
dplyr
包的一部分:

library(dplyr)

iris %>%
  group_by(Species) %>%
  group_modify(~ broom::tidy(lm(Petal.Length ~ Sepal.Length, data = .x)))
#> # A tibble: 6 × 6
#> # Groups:   Species [3]
#>   Species    term         estimate std.error statistic  p.value
#>   <fct>      <chr>           <dbl>     <dbl>     <dbl>    <dbl>
#> 1 setosa     (Intercept)     0.803    0.344      2.34  2.38e- 2
#> 2 setosa     Sepal.Length    0.132    0.0685     1.92  6.07e- 2
#> 3 versicolor (Intercept)     0.185    0.514      0.360 7.20e- 1
#> 4 versicolor Sepal.Length    0.686    0.0863     7.95  2.59e-10
#> 5 virginica  (Intercept)     0.610    0.417      1.46  1.50e- 1
#> 6 virginica  Sepal.Length    0.750    0.0630    11.9   6.30e-16
© www.soinside.com 2019 - 2024. All rights reserved.