lm():循环导出导出F统计量p值的多个线性模型

时间:2016-06-17 21:45:03

标签: r loops regression linear-regression lm

我有一个大型数据集,我需要运行一个比较组的线性模型。 我需要使用线性模型找到组比较的p值。有四组(所以我需要1~2,1~3.1~4,2~3,2~4,3~4)并且有130列需要比较来自这些组的数据。任何帮助将不胜感激!!

我有这个,这正是我所需要的。

fit<-lm(variable~group, data=data)
summary(fit)

但是,对于所有组和列,我有近800个比较,所以我想避免手动执行此操作。我尝试编写for循环,但它无法正常工作。

k<-data.frame()
for (i in 1:130){
 [i,1]<-colnames(data)
 fit<- lm(i~group, data=data)
 [i,2] <- fit$p.value
}

但这给了我各种不同的错误。我真的只需要p值。非常感谢帮助!!谢谢!

2 个答案:

答案 0 :(得分:1)

(2016-06-18)现阶段您的问题不完全负责。在下文中,我将指出几个问题。

如何正确获取p值

我假设你想要模型的F统计值的p值,作为拟合优度的指示。假设你的拟合模型是fit,我们应该这样做:

fstatistic <- summary(fit)$fstatistic
p_value <- unname(1 - pf(fstatistic[1], fstatistic[2], fstatistic[3]))

例如,我将使用内置数据集trees作为演示。

fit <- lm(Height ~ Girth, trees)
## truncated output of summary(fit)
# > summary(fit)
# Residual standard error: 5.538 on 29 degrees of freedom
# Multiple R-squared:  0.2697,  Adjusted R-squared:  0.2445 
F-statistic: 10.71 on 1 and 29 DF,  p-value: 0.002758

fstatistic <- summary(fit)$fstatistic
p_value <- unname(1 - pf(fstatistic[1], fstatistic[2], fstatistic[3]))
## > p_value
# [1] 0.002757815

因此,p_value同意打印的摘要。

您的循环

我建议你在计算/更新过程中使用向量而不是数据帧。

variable <- character(130)
p.value <- numeric(130)

您可以通过以下结果将结果结合到数据框中:

k <- data.frame(var = variable, p.value = p.value)

为什么呢?因为这是内存效率高!现在,经过这些修正,我们到达:

variable <- character(130)
p.value <- numeric(130)
for (i in 1:130) {
  variable[i] <- colnames(data)
  fit <- lm(i~group, data=data)
  fstatistic <- summary(fit)$fstatistic
  p_value <- unname(1 - pf(fstatistic[1], fstatistic[2], fstatistic[3]))
  p.value[i] <- p_value
  }
k <- data.frame(var = variable, p.value = p.value)

其他问题

我仍然认为上面的代码不起作用。因为我不确定以下是否正确:

  variable[i] <- colnames(data)
  fit <- lm(i~group, data=data)
  1. 在循环过程中,data未更改,因此colnames(data)会返回一个向量,因此var[i] <- colnames(data)将触发错误。
  2. i~group看起来很奇怪。您的i
  3. 中有data吗?

    我无法帮你解决这些问题。我不知道你的data是什么样的。但是如果你可以放入一部分数据,那就没关系了。

    跟进(2016-06-19)

      

    谢谢。这非常有帮助。我的数据中没有“i”,但我希望我可以使用它来表示不同的列名,以便它遍历所有这些。有没有办法分配列名数字,以便这可以工作?

    是的,但我需要知道每列的内容。

      

    第1列有一个组号。以下列包含我正在查看的不同因素的数据。

    好的,我想ncol(data) = 131,其中第一列是group,其余130列是您要测试的。然后这应该工作:

    variable <- colnames(data)[-1]
    p.value <- numeric(130)
    for (i in 1:130) {
      fit <- lm(paste(variable[i], "group", sep = "~"), data=data)
      fstatistic <- summary(fit)$fstatistic
      p_value <- unname(1 - pf(fstatistic[1], fstatistic[2], fstatistic[3]))
      p.value[i] <- p_value
      }
    k <- data.frame(var = variable, p.value = p.value)
    

    可以使用sapply()代替上述 for 循环。但我认为没有性能差异,因为与lm()summary()相比,循环开销非常小。

答案 1 :(得分:0)

我认为这可以让你至少开始。它使用dplyr和扫帚包。基本思想是将所需的所有公式定义为字符,然后使用lapply()通过lm()运行它们。

library(dplyr)
library(broom)

# Generate a vector of wanted formulas
forms <- c("mpg ~ cyl", "mpg ~ wt")

# Function to apply formula
lmit <- function(form){
  tidy(lm(as.formula(form), mtcars)) %>% 
    mutate(formula = form)
}

# Apply it and bind into a dataframe
results <- bind_rows(lapply(forms, lmit))