简体   繁体   中英

Problem with finding the slope of linear regression in ggplot2

I'm making a loop to create some boxplots with ggplot and add a linear regression line in them. That worked just fine, however I try to modify the loop to also calculate the slope of each individual linear regression and input them in a different df but with no luck

"y"i contains the value for each point and "df"i is the dataframe with the values of the "y"i and the 6 different periods

The result is 49 graphs like this one and basically I struggle to find the way to calculate the slope of everyone of them and input them all in a different df在此处输入图像描述

for (i in 1:49) {
  name1<-paste0("y",i,sep="")
  name2<-paste0("df",i,sep="")

  mypath<-file.path(path[i])
  jpeg(file = mypath,width = 1800, height = 600)
  print(ggplot(data=get(name2), aes(x=Periods, y=get(name1))) +
          geom_bar(stat="identity", width=0.5,fill="steelblue") +
          geom_smooth(aes(x = Periods, y = get(name1), group=1),
                      method = "lm", se= FALSE, color = "firebrick", size = 2)+
          labs(x = "Time Periods") +
          labs(y="Number of tropical nights")  +
          ylim(0,10)+
          ggtitle("Number of tropical nights per time period (Tmin > 20°C)")+ theme(plot.title = element_text(hjust = 0.5)))
  dev.off()
}

Based on what you have now, the below should work:

#simulate data

df1 <- data.frame(Periods=rnorm(10),y1=rnorm(10))
df2 <- data.frame(Periods=rnorm(10),y2=rnorm(10))
df3 <- data.frame(Periods=rnorm(10),y3=rnorm(10))

# list to store results

results = vector("list",3)

for(i in 1:3) {
  name1<-paste0("y",i,sep="")
  name2<-paste0("df",i,sep="")
  FORMULA = as.formula(paste(name1,"~ Periods"))
  COEF = as.numeric(coefficients(lm(FORMULA,data=get(name2))))
  results[[i]] <- data.frame(
         name1=name1,
         name2=name2,
         intercept=COEF[1],
         coefficient=COEF[2]
  )
}

do.call(rbind,results)

Still it's a bit messy to have 50 dfs floating around? Why not try something like this:

# do not split your dfs, or just combine them like this
DF <-data.frame(
Periods=rnorm(30),y=rnorm(30),
df=paste("df",rep(1:3,each=10),sep="")
)
library(lme4)
coefficients(lmList(y ~ Periods | df,data=DF))
    (Intercept)     Periods
df1   0.2931990 -0.44942868
df2   0.1146975  0.01613812
df3  -0.3491186  0.11273944

I tried an alternative solution, making the graph showing the slope in each case using the code below

x<-0
for (i in 1:6) {
  x[i]<-i
}

x<-as.numeric(x)

for (i in 1:49) {
  name1<-paste0("y",i,sep="")
  name2<-paste0("df",i,sep="")

  name4<-paste0("stats",i,sep="")
  name5<-paste0("slope",i,sep="")
  assign(name4,lm(x~get(name1), data=get(name2)))
  assign(name5,get(name4)[[1]][2])

  mypath<-file.path(path[i])
  jpeg(file = mypath,width = 1800, height = 600)
  print(ggplot(data=get(name2), aes(x=Periods, y=get(name1))) +
          geom_bar(stat="identity", width=0.5,fill="steelblue") +
          annotate("text", x=1.5, y=22, label= get(name5), size=8) +
          annotate("text", x=0.75, y=22, label= "Slope=", size=8) +
          geom_smooth(aes(x = Periods, y = get(name1), group=1),
                      method = "lm", se= FALSE, color = "firebrick", size = 2)+
          labs(x = "Time Periods") +
          labs(y="Number of tropical nights")  +
          ylim(0,25)+
          ggtitle("Number of tropical nights per time period (Tmin > 20°C)")+ theme(plot.title = element_text(hjust = 0.5)))
  dev.off()
}

and it generated graphs like this one在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM