Performing lm() and segmented() on multiple columns in R

亡梦爱人 提交于 2019-12-03 04:05:42

Here's an approach using tidyverse and broom to return a data frame containing the results for each Curve column:

library(broom)
library(tidyverse)

model.results = setNames(names(dat[,-1]), names(dat[,-1])) %>% 
  map(~ lm(paste0(.x, " ~ x"), data=dat) %>% 
        segmented(seg.Z=~x) %>%
        list(model=tidy(.), 
             psi=data.frame(term="breakpoint", estimate=.[["psi.history"]][[5]]))) %>%
  map_df(~.[2:3] %>% bind_rows, .id="Curve")

model.results
    Curve        term   estimate  std.error   statistic      p.value
1  Curve1 (Intercept)  95.866127 0.14972382  640.286416 1.212599e-42
2  Curve1           x -12.691455 0.05220412 -243.112130 1.184191e-34
3  Curve1        U1.x  10.185816 0.11080880   91.922447 1.233602e-26
4  Curve1      psi1.x   0.000000 0.02821843    0.000000 1.000000e+00
5  Curve1  breakpoint   5.595706         NA          NA           NA
6  Curve2 (Intercept)  94.826309 0.45750667  207.267599 2.450058e-33
7  Curve2           x  -9.489342 0.11156425  -85.057193 5.372730e-26
8  Curve2        U1.x   6.532312 1.17332640    5.567344 2.275438e-05
9  Curve2      psi1.x   0.000000 0.23845241    0.000000 1.000000e+00
10 Curve2  breakpoint   7.412087         NA          NA           NA
11 Curve3 (Intercept) 100.027990 0.29453941  339.608175 2.069087e-37
12 Curve3           x  -8.931163 0.08154534 -109.523900 4.447569e-28
13 Curve3        U1.x   2.807215 0.36046013    7.787865 2.492325e-07
14 Curve3      psi1.x   0.000000 0.26319757    0.000000 1.000000e+00
15 Curve3  breakpoint   6.362132         NA          NA           NA

You can wrap the whole thing in a function, taking as the arguments the column name and the data, and use lapply on the column names, like this:

library(segmented)
run_mod <- function(varname, data){

  data$Y <- data[,varname]
  model <- lm(Y ~ x, data) # Linear model
  seg_model <- segmented(model, seg.Z = ~x) # Segmented model
  breakpoint <- as.matrix(seg_model$psi.history[[5]]) # Extract breakpoint
  coefficients <- as.matrix(seg_model$coefficients) # Extract coefficients
  summary_curve1 <- as.data.frame(rbind(breakpoint, coefficients)) 
  colnames(summary_curve1) <- varname

return(summary_curve1)
}


lapply(names(dat)[2:ncol(dat)], function(x)run_mod(x, dat))

Which gives the summary for each fitted curve (not sure which output you actually want).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!