-3

I want to plot linear-model-lines for each ID.

How can I create predictions for multiple lms (or glms) using sequences of different length? I tried:

#some fake data
res<-runif(60,1,20)
var<-runif(60,10,50)
ID<-rep(c("A","B","B","C","C","C"),10)
data<- data.frame(ID,res,var)

#lm
library(data.table)
dt <- data.table(data,key="ID")
fits <- lapply(unique(data$ID),
function(z)lm(res~var, data=dt[J(z),], y=T))

#sequence for each ID of length var(ID)
mins<-matrix(with(data, tapply(var,ID,min)))
mins1<-mins[,1]
maxs<-matrix(with(data,tapply(var,ID,max)))
maxs1<-maxs[,1]
my_var<-list()
for(i in 1:3){
 my_var[[i]]<- seq(from=mins1[[i]],to=maxs1[[i]],by=1)
}

# predict on sequences
predslist<- list()
predslist[[i]] <- for(i in 1:3){
  dat<-fits[[i]]
  predict(dat,newdata= data.frame("var"= my_var,type= "response", se=TRUE))
}

predict results error

F.Johann
  • 25
  • 4
  • 2
    So where exactly are you stuck? The plotting part? What do you want the plot to look like exactly? I'm not sure I understand your desired output. – MrFlick Jun 14 '17 at 23:19
  • Does this answer your question? https://stackoverflow.com/questions/24356683/apply-grouped-model-back-onto-data/24356753#24356753 That was one of three hits to this SO search. – IRTFM Jun 15 '17 at 00:11
  • Further question: ???lms. I see no `lms` package in CRAN. Some sort of code omission must have occurred. – IRTFM Jun 15 '17 at 01:04
  • I am stuck at the last part of the script where I want to predict the models on the sequenses. The desired output is a plot with one line for each ID. The line shows the lm-predictions for ID[i] along the sequence[i] which has the range from min to max of var for ID[i] – F.Johann Jun 15 '17 at 16:17

2 Answers2

1

Plotting lm lines only for var[i] ranges works in ggplot:

library(ggplot2)
# create ID, x, y as coded by Matt
p <- qplot(x, y)
p + geom_smooth(aes(group=ID), method="lm", size=1, se=F)
F.Johann
  • 25
  • 4
0

Is something like this what you're after?

# generating some fake data
ID <- rep(letters[1:4],each=10)
x <- rnorm(40,mean=5,sd=10)
y <- as.numeric(as.factor(ID))*x + rnorm(40)

# plotting in base R
plot(x, y, col=as.factor(ID), pch=16)

# calling lm() and adding lines
lmlist <- lapply(sort(unique(ID)), function(i) lm(y[ID==i]~x[ID==i]))
for(i in 1:length(lmlist)) abline(lmlist[[i]], col=i)

Don't know if the plotting part is where you're stuck, but the abline() function will draw a least-squares line if you pass in an object returned from lm().

If you want the least-squares lines to begin & end with the min & max x values, here's a workaround. It's not pretty, but seems to work.

plot(x, y, col=as.factor(ID), pch=16)
IDnum <- as.numeric(as.factor(ID))
for(i in 1:length(lmlist)) lines(x[IDnum==i], predict(lmlist[[i]]), col=i)
Matt Tyers
  • 2,125
  • 1
  • 14
  • 23