在R中的数据框的几列上运行多个线性回归

时间:2019-02-27 14:29:06

标签: r dataframe regression

我有一个这样构成的数据集: enter image description here

我想使用V1,V2等运行线性回归模型和ANOVA。分别作为自变量和g列作为因变量(即lm(V1〜g),lm(V2〜g),依此类推)。这将很简单,除了需要在对列中按级别对这些线性回归进行分组之外,例如,我的输出对所有具有对1.1的行都包含lm(V1〜g),对于所有对都包含lm(V1〜g)对1.201,等等。

我尝试了多种使用for循环,lapply和data.table包的方法,但是没有任何东西可以准确地提供我想要的输出。谁能给我任何有关解决此问题的最佳方法的见识?

编辑: 我的完整数据集在对列和100 V列(V1 ... V100)中有7056个不同的对。我对这个问题的最新尝试:

df$pair <- as.factor(df$pair)
out <- list()
for (i in 3:ncol(df)){
    out[[i]] <- lapply(levels(df$pair), function(x) {
    data.frame(df=x, g = coef(summary(lm(df[,i]~ df$g, data=df[df$pair==x,])),row.names=NULL))})
    }

2 个答案:

答案 0 :(得分:1)

使用tidyverse包来过滤您的数据框:

library(tidyverse)

lm(V1~g, data=filter(yourData, pair==1.1))
lm(V2~g, data=filter(yourData, pair==1.201))

这可确保您消除每个回归模型不包含所需pair值的行。您可能可以创建一个循环来执行此操作,但是我认为仅通过pair值手动进行过滤会更容易。如果您真的想使用循环,这是一种相当简单的方法:

for (i in levels(yourData$pair)) {
  if (i==1.1) {
    mod1 <- lm(V1~g, data=filter(yourData, pair==i))
  }

  if (i==1.201) {
    mod2 <- lm(V2~g, data=filter(yourData, pair==i))
  }
}

但这仍然是手动遍历pair的各个级别。我将不得不查看您的整个数据集以使循环过程自动化。

此外,如果g列包含您的从属值,则调用应为lm(g~V1)lm(g~V2)等。不应为{{ 1}}。

答案 1 :(得分:1)

让我们在这里获得tidyversebroom的力量,并放弃所有这些循环...

首先,我将创建一个虚拟表:

df <- data.frame(
  g = runif(50), 
  pair = sample(x = c("A", "B", "C"), size = 50, replace = TRUE), 
  V1 = runif(50), 
  V2 = runif(50), 
  V3 = runif(50), 
  V4 = runif(50), 
  V5 = runif(50),
  stringsAsFactors = FALSE
)

这大约是您的数据结构的样子。现在看一下代码的内容:

library(tidyverse)
library(broom)

df %>% 
  as_tibble %>% 
  gather(key = "column", value = "value", V1:V5) %>%       # first set the data in long format
  nest(g, value) %>%                                       # now nest the dependent and independent factors
  mutate(model = map(data, ~lm(g ~ value, data = .))) %>%  # fit the model using purrr
  mutate(tidy_model = map(model, tidy)) %>%                # clean the model output with broom
  select(-data, -model) %>%                                # remove the "untidy" parts
  unnest()                                                 # get it back in a recognizable data frame

这给了我们以下内容:

# A tibble: 30 x 7
   pair  column term        estimate std.error statistic  p.value
   <chr> <chr>  <chr>          <dbl>     <dbl>     <dbl>    <dbl>
 1 C     V1     (Intercept)  0.470       0.142    3.31   0.00561 
 2 C     V1     value        0.125       0.265    0.472  0.645   
 3 B     V1     (Intercept)  0.489       0.142    3.45   0.00359 
 4 B     V1     value       -0.0438      0.289   -0.151  0.882   
 5 A     V1     (Intercept)  0.515       0.111    4.63   0.000279
 6 A     V1     value       -0.00569     0.249   -0.0229 0.982   
 7 C     V2     (Intercept)  0.367       0.147    2.50   0.0265  
 8 C     V2     value        0.377       0.300    1.26   0.231   
 9 B     V2     (Intercept)  0.462       0.179    2.59   0.0206  
10 B     V2     value        0.0175      0.322    0.0545 0.957   
# … with 20 more rows

是的,好漂亮!请注意,我使用的是lm(g ~ value)而不是lm(value ~ g),因为这是您的文字描述所暗示的。