1

I have the following code which creates a plot for, the data is located here Data

data<-lidar
x<-lidar$range
y<-lidar$logratio
h<-20
par(mfrow=c(2,2))

r<-max(x)-min(x)
bn<-ceiling(r/h)
binwidth=c(5,10,30,100)
  
  
#Creates a matrix to handle the data of same length
W<-matrix(nrow=length(x),ncol=bn)
for (j in 1:bn){
  for (i in 1:length(x)){
    if (x[i]>=(min(x)+(j-1)*h) && x[i]<=(min(x)+(j)*h)){W[i,j]=1}
    else {W[i,j]=0}
  }
}

#Sets up the y-values of the bins
fit<-rep(0,bn)
for (j in 1:bn){
  fit[j]<- sum(y*W[,j]/sum(W[,j]))
}

#Sets up the x values of the bins
t<-numeric(bn)
for (j in 1:bn){
  t[j]=(min(x)+0.5*h)+(j-1)*h
}

plot(x,y)
lines(t,fit,type = "S", col = 1, lwd = 2)

This creates a single plot in the left corner of a page since I have

par(mfrow=c(2,2))

Is there a way to create a for statement that will plot 4 graphs for me on that one page using h values of 5,10,30,100 (The values provided by the variable binwidth) so I don't have to manually change my h value every time to reproduce a new plot so my final result appears like this,

enter image description here

Essentially I want to run the code 4 times with different values of h using another for statement that plots all 4 results without me changing h all the time. Any help or hints are greatly appreciated.

2 Answers 2

3

Here's a fully reproducible example that loads the data directly from the url then uses the apply family to iterate through the different plots

lidar <- read.table(paste0("http://www.stat.cmu.edu/%7Elarry",
                           "/all-of-nonpar/=data/lidar.dat"),
                    header = TRUE)

par(mfrow = c(2, 2))

breaks <- lapply(c(5, 10, 30, 100), function(i) {
                   val <- seq(min(lidar$range), max(lidar$range), i)
                   c(val, max(val) + i)})

means <- lapply(breaks, function(i) {
            vals <- tapply(lidar$logratio, 
                    cut(lidar$range, breaks = i, include.lowest = TRUE), mean)
            c(vals[1], vals)})

invisible(mapply(function(a, b) {
  plot(lidar$range, lidar$logratio)
  lines(a, b, type = "S", lwd = 2)
  }, breaks, means))

enter image description here

Created on 2020-09-25 by the reprex package (v0.3.0)

Sign up to request clarification or add additional context in comments.

1 Comment

Wow, this is a much shortened version of the code I had set up and I actually forgot that you can read data straight from a web link as long as the link is still active. My knowledge of the lapply, salppy and mapply functions is still a little lackluster so I'll need to review them to fully understand the code. Thanks.
2

Answering directly your question: keep the same other parameters:

data<-lidar
x<-lidar$range
y<-lidar$logratio
h<-20
par(mfrow=c(2,2))

r<-max(x)-min(x)
bn<-ceiling(r/h)
binwidth=c(5,10,30,100)

do a plot function (not necessary, but good practice)

doplot = function(h){
  #Creates a matrix to handle the data of same length
  W<-matrix(nrow=length(x),ncol=bn)
  for (j in 1:bn){
    for (i in 1:length(x)){
      if (x[i]>=(min(x)+(j-1)*h) && x[i]<=(min(x)+(j)*h)){W[i,j]=1}
      else {W[i,j]=0}
    }
  }
  
  #Sets up the y-values of the bins
  fit<-rep(0,bn)
  for (j in 1:bn){
    fit[j]<- sum(y*W[,j]/sum(W[,j]))
  }
  
  #Sets up the x values of the bins
  t<-numeric(bn)
  for (j in 1:bn){
    t[j]=(min(x)+0.5*h)+(j-1)*h
  }

  
  plot(x,y)
  lines(t,fit,type = "S", col = 1, lwd = 2)
}

and then loop on the h parameter

for(h in c(5,10,30,100)){
  doplot(h)
}

A general comment: you could gain a lot learning how to use the data.frames, a bit of dplyr or data.table and ggplot2 to do that. I feels that you could replicate your entire code + plots in 10 more comprehensible lines.

1 Comment

Thanks for the input on this, I hadn't considered defining it into a function as I was thinking it would just be another form of a for statement and yes I do agree that this code could be shortened quite a bit and something I have always struggled within R.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.