dplyr和tidyr - 使用因子一次计算多个线性模型

4

在进一步了解 tidyverse 后,我开始像 这篇文章中所描述的那样一次拟合多个线性模型。换句话说,我会按照以下方式进行操作:

library(dplyr)
library(tidyr)
library(purrr)
df <- data.frame(y = rnorm(10), 
                 x1 = runif(10),
                 x2 = runif(10))

df %>%
  gather(covariate, value, x1:x2) %>% 
  group_by(covariate) %>% 
  nest() %>% 
  mutate(model = map(.x = data , .f = ~lm(y ~ value, data = .))) %>% 
  mutate(rsquared = map_dbl(.x = model, .f = ~summary(.)$r.squared))

问题在于,当变量类型不同时,例如一个是数字,另一个是因子时,这种方法就会失败,因为gather()函数会将整个value向量强制转换为因子。例如,
df <- data.frame(y = rnorm(10), 
                 x1 = runif(10),
                 x3 = sample(c("a", "b", "c"), 10, replace = TRUE))

df %>%
  gather(covariate, value, x1:x3) %>% 
  sapply(class)

后面跟着警告信息

Warning message:
attributes are not identical across measure variables; they will be dropped 

          y   covariate       value 
  "numeric" "character" "character" 

并且value列是字符型的,所以使用nest()的技巧将不再起作用,因为所有协变量都将被视为因子。

我想知道是否有一种整洁的方法来解决这个问题。

1个回答

3

你可以在拟合模型时转换类型,但是要小心处理,因为评论中指出这可能会产生意想不到的后果。

如果你仍然想进行转换,可以使用readr中的type_convert对整个框架进行转换,或者只对"value"向量使用type.convert

使用type_convert

mutate(model = map(.x = data , .f = ~lm(y ~ value, data = readr::type_convert(.))))

使用 type.convert 函数:
mutate(model = map(.x = data , .f = ~lm(y ~ type.convert(value), data = .)))

在这种情况下,这些中的任何一个作为链的一部分都会导致所需的结果:

df %>%
    gather(covariate, value, x1:x3) %>% 
    group_by(covariate) %>% 
    nest() %>% 
    mutate(model = map(.x = data , .f = ~lm(y ~ type.convert(value), data = .))) %>% 
    mutate(rsquared = map_dbl(.x = model, .f = ~summary(.)$r.squared))

# A tibble: 2 x 4
  covariate              data    model   rsquared
      <chr>            <list>   <list>      <dbl>
1        x1 <tibble [10 x 2]> <S3: lm> 0.33176960
2        x3 <tibble [10 x 2]> <S3: lm> 0.06150498

巧妙的方法。+1 - Steven Beaupré
2
如果您恰好有看起来像数字的变量,但实际上应该被视为因子进行处理(也许不是一个好主意,但这种情况经常发生),那么将会失败。使用“gather”将不可避免地丢失一些信息... - Ben Bolker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接