Combaning Multiple plots into a Single plot - r
I am writing a code to generate four stimulations and then generate graphs. My code works, but I want instead of generating four graphs I want to combine them all in one graph. How can I do that?
My code:
queueSimulation <- function(arriverate, servrate, endtime) {
queue = numeric(0)
arrivetimes = rexp(10000, arriverate)
servtimes = rexp(10000, servrate)
clock = 0.0
clist=c()
qlist=c()
while(clock <= endtime) {
if(length(queue) > 0 && queue[1] < arrivetimes[1]) {
clock = clock + queue[1]
queue = queue[-1]
}
else {
clock = clock + arrivetimes[1]
queue[length(queue) + 1] = servtimes[1]
arrivetimes = arrivetimes[-1]
servtimes = servtimes[-1]
}
#queue_size= length(round(clock, 2))
clist = c(clist , clock)
qlist = c(qlist , length(queue))
}
a<-data.frame(time=clist , qsize=qlist)
print(a)
mean1<-mean(qlist)
cat("Average :", mean1, "\n")
plot(a)
}
and calling the function:
queueSimulation(1.0, 5.0, 100)
queueSimulation(2.0, 4.0, 100)
queueSimulation(2.3, 3.5, 100)
queueSimulation(4.0, 5.0, 100)
There might be a better solution to this, but how about slightly changing your approach.
1- In your function, add two variables, one for color (cl) and one to tell your function if your plotting the main plot or just adding lines (pl). 1 for main and 0 for lines.
function(arriverate, servrate, endtime,cl,pl) {
2- call your plot with an if statement, and fix your y axis to range from 0 to 200.
if(pl==1){plot(a,col=cl,ylim=c(0,200),type="l")} else{lines(a,col=cl)}}
and then, call your function with theses two variables (cl and pl) :
queueSimulation(1.0, 5.0, 100,"red",1)
queueSimulation(2.0, 4.0, 100,"blue",0)
queueSimulation(2.3, 3.5, 100,"green",0)
queueSimulation(4.0, 5.0, 100,"black",0)
The problem I see with this is that your simulations can get values way over 200 for the y axis, maybe try to find a way to get max y values in one of your call.
Take a look at layout, specifically put layout(matrix(1:4,nrow=2)) (or a variant) before you call your plotting functions.
Related
Store plots in an array
I am trying to plot histograms of different columns of a dataframe in subplots. plt_count = 1 for i = names(abalone)[2:end] p[plt_count]=histogram(abalone[:,i]) plt_count += 1 end plot(p, layout=(3,3), legend=false) This is what I tried. But I can't come up with the right definition for the array p. How do I define p? Improvements to the code will also be helpful.
If you don't care about the type stability, you can make Any type array. ps = Array{Any}(nothing, 3) ps[1] = plot([2,3,4]) ps[2] = plot([1,5]) ps[3] = plot([10,5,1,0]) #show typeof(ps) plot(ps..., layout=(3,1)) If you want to create an array of Plot type specifically, one approach is to initialize an array with a dummy plot, then replace later. ps = repeat([plot(1)], 3) ps[1] = plot([2,3,4]) ps[2] = plot([1,5]) ps[3] = plot([10,5,1,0]) #show typeof(ps) plot(ps..., layout=(3,1))
decimal increments in loop for R
I would like to find the value of "p" below (which is between 0 and 1), knowing the following equations: RI_26 = min(IR,na.rm=FALSE) RI_min = 100-(sse*SUM/((1+p)*Dotation2017*100))^(1/p) where RI_26 is the minimum of resources index of my 26 area. It is a constant in my case. In RI_min, sse and Dotations2017 are 2 constants and p is a unknown. I know that RI_26 should be equal to RI_min. It would be easy to solve it, but SUM (which is present in RI_min) is as well unknown as it is a function of p as following: `sum.function = function(p){ SUM <- c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) for(i in 1:length(Canton)) if(IR[i] < 100) { SUM[i] <- (100-IR[i])^(1+p)*Pop[i] SUM[27] <- SUM[27]+SUM[i] } SUM <- round(SUM,0) return(SUM[27]) } SUM = sum.function(p) SUM returns a number (or vector 1X1). To deal with it, I would like to find the value of p that satisfied: RI_26/RI_min = 1 To do so, I would like to do a loop, beginning with p = 0 and then increasing the value of p by 0.01 until it reaches 1. The loop should return the value of p_star when the constraint is True (RI_26/RI_min = 1.00). I don't have any idea how to do this but it could look like the following code: p.function = function(){ for(...) if(RI_26/RI_min = 1.000000) { p_star <- p } return(p_star) } So the function will return the value of p_star when RI_26/RI_min = 1.000000. What am I suppose to write in my function: p.function to increment "p" and have the result that I want? Any idea?
for (i in seq(0, 1, by = 0.1)) { "Your code here" }
How to use a for loop to fill in an array by two rows at one time in R?
I want to use the data of [x] to fill in [test] based on certain sequence: x = matrix(rnorm(330),165,2) origins = 130:157 horizon = 8 col = 1:2 test = array(0, c(length(origins)*length(col), horizon)) for( origin in origins){ for (c in col){ test[which(origin==origins), ] = x[(origin+1):(origin+8), c] } } However, this code only helps extract the second column of [x] to fill in the first 28 rows of [test]. The following picture is only a part of a complete [test] table, showing the ineffective filling from row 29 to row 56. enter image description here Anyone who can help me fill in them completely? Thank you very much.
Here is a possible solution, but it is still not clear what you want the result to be. better to make much smaller data and show desired result. The left hand side of the assignment, in the original code, does not vary with c, so each time through the loop for c the same rows of test will be overwrittem, x = matrix(rnorm(330),165,2) origins = 130:157 horizon = 8 col = 1:2 test = array(0, c(length(origins)*length(col), horizon)) for( origin in origins){ for (c in col){ # the left hand side must vary somehow with c as well. test[(which(origin==origins)-1) + (c - 1) * length(origins) + 1, ] = x[(origin+1):(origin+8), c] } }
R fit user defined distribution
I am trying to fit my own distribution to my data, find the optimum parameters of the distribution to match the data and ultimately find the FWHM of the peak in the distribution. From what I've read, the package fitdistrplus is the way to do this. I know the data takes the shape of a lorentzian peak on a quadratic background. plot of the data: plot of raw data The raw data used: data = c(0,2,5,4,5,4,3,3,2,2,0,4,4,2,5,5,3,3,4,4,4,3,3,5,5,6,6,8,4,0,6,5,7,5,6,3,2,1,7,0,7,9,5,7,5,3,5,5,4,1,4,8,10,2,5,8,7,14,7,5,8,4,2,2,6,5,4,6,5,7,5,4,8,5,4,8,11,9,4,8,11,7,8,6,9,5,8,9,10,8,4,5,8,10,9,12,10,10,5,5,9,9,11,19,17,9,17,10,17,18,11,14,15,12,11,14,12,10,10,8,7,13,14,17,18,16,13,16,14,17,20,15,12,15,16,18,24,23,20,17,21,20,20,23,20,15,20,28,27,26,20,17,19,27,21,28,32,29,20,19,24,19,19,22,27,28,23,37,41,42,34,37,29,28,28,27,38,32,37,33,23,29,55,51,41,50,44,46,53,63,49,50,47,54,54,43,45,58,54,55,67,52,57,67,69,62,62,65,56,72,75,88,87,77,70,71,84,85,81,84,75,78,80,82,107,102,98,82,93,98,90,94,118,107,113,103,99,103,96,108,114,136,126,126,124,130,126,113,120,107,107,106,107,136,143,135,151,132,117,118,108,120,145,140,122,135,153,157,133,130,128,109,106,122,133,132,150,156,158,150,137,147,150,146,144,144,149,171,185,200,194,204,211,229,225,235,228,246,249,238,214,228,250,275,311,323,327,341,368,381,395,449,474,505,529,585,638,720,794,896,919,1008,1053,1156,1134,1174,1191,1202,1178,1236,1200,1130,1094,1081,1009,949,890,810,760,690,631,592,561,515,501,489,467,439,388,377,348,345,310,298,279,253,257,259,247,237,223,227,217,210,213,197,197,192,195,198,201,202,211,193,203,198,202,174,164,162,173,170,184,170,168,175,170,170,168,162,149,139,145,151,144,152,155,170,156,149,147,158,171,163,146,151,150,147,137,123,127,136,149,147,124,137,133,129,130,128,139,137,147,141,123,112,136,147,126,117,116,100,110,120,105,91,100,100,105,92,88,78,95,75,75,82,82,80,83,83,66,73,80,76,69,81,93,79,71,80,90,72,72,63,57,53,62,65,49,51,57,73,54,56,78,65,52,58,49,47,56,46,43,50,43,40,39,36,45,28,35,36,43,48,37,36,35,39,31,24,29,37,26,22,36,33,24,31,31,20,30,28,23,21,27,26,29,21,20,22,18,19,19,20,21,20,25,18,12,18,20,20,13,14,21,20,16,18,12,17,20,24,21,20,18,11,17,12,5,11,13,16,13,13,12,12,9,15,13,15,11,12,11,8,13,16,16,16,14,8,8,10,11,11,17,15,15,9,9,13,12,3,11,14,11,14,13,8,7,7,15,12,8,12,14,9,5,2,10,8) I have calculated the equations which define the distribution and cumulative distribution: dFF <- function(x,a,b,c,A,gamma,pos) a + b*x + (c*x^2) + ((A/pi)*(gamma/(((x-pos)^2) + (gamma^2)))) pFF <- function(x,a,b,c,A,gamma,pos) a*x + (b/2)*(x^2) + (c/3)*(x^3) + A/2 + (A/pi)*(atan((x - pos)/gamma)) I believe these to be correct. From what I understand, a distribution fit should be possible using just these definitions using the fitdist (or mledist) method: fitdist(data,'FF', start = list(0,0.3,-0.0004,70000,13,331)) mledist(data,'FF', start = list(0,0.3,-0.0004,70000,13,331)) This returns the statement 'function cannot be evaluated at initial parameters> Error in fitdist(data, "FF", start = list(0, 0.3, -4e-04, 70000, 13, 331)):the function mle failed to estimate the parameters, with the error code 100' in the first case and in the second I just get a list of 'NA' values for the estimates. I then calculated a function to give the quantile distribution values to use the other fitting methods (qmefit): qFF <- function(p,a,b,c,A,gamma,pos) { qList = c() axis = seq(1,600,1) aF = dFF(axis,a,b,c,A,gamma,pos) arr = histogramCpp(aF) # change data to a histogram format for(element in 1:length(p)){ q = quantile(arr,p[element], names=FALSE) qList = c(qList,q) } return(qList) } Part of this code requires calling the c++ function (by using the library Rcpp): #include <Rcpp.h> #include <vector> #include <math.h> using namespace Rcpp; // [[Rcpp::export]] std::vector<int> histogramCpp(NumericVector x) { std::vector<int> arr; double number, fractpart, intpart; for(int i = 0; i <= 600; i++){ number = (x[i]); fractpart = modf(number , &intpart); if(fractpart < 0.5){ number = (int) intpart; } if(fractpart >= 0.5){ number = (int) (intpart+1); } for(int j = 1; j <= number; j++){ arr.push_back(i); } } return arr; } This c++ method just turns the data into a histogram format. If the first element of the vector describing the data is 4 then '1' is added 4 times to the returned vector etc. . This also seems to work as sensible values are returned. plot of the quantile function: Plot of quantiles returned for probabilities from 0 to 1 in steps of 0.001 The 'qmefit' method can then be attempted through the fitdist function: fitdist(data,'FF', start = list(0,0.3,-0.0004,70000,13,331), method = 'qme', probs = c(0,0.3,0.4,0.5,0.7,0.9)) I chose the 'probs' values randomly as I don't fully understand their meaning. This either straight-up crashes the R session or after a brief stuttering returns a list of 'NA' values as estimates and the line <std::bad_alloc : std::bad_alloc> I am not sure if I am making a basic mistake here and any help or recommendations are appreciated.
In the end I managed to find a work-around for this using the rPython package and lmfit from python. It solved my issue and might be useful for others with the same issue. The R-code was as follows: library(rPython) python.load("pyFit.py") python.assign("row",pos) python.assign("vals",vals) python.exec("FWHM,ERROR,FIT = fitDist(row,vals)") FWHM = python.get("FWHM") ERROR = python.get("ERROR") cFIT = python.get("FIT") and the called python code was: from lmfit import Model, minimize, Parameters, fit_report from sklearn import mixture import numpy as np import matplotlib.pyplot as plt import math def cauchyDist(x,a,b,c,d,e,f,g,A,gamma,pos): return a + b*x + c*pow(x,2) + d*pow(x,3) + e*pow(x,4) + f*pow(x,5) + g*pow(x,6) + (A/np.pi)*(gamma/((pow((x-pos),2)) + (pow(gamma,2)))) def fitDist(row, vals): gmod = Model(cauchyDist) x = np.arange(0,600) result = gmod.fit(vals, x=x, a = 0, b = 0.3, c = -0.0004, d = 0, e = 0, f= 0, g = 0, A = 70000, gamma = 13, pos = row) newFile = open('fitData.txt', 'w') newFile.write(result.fit_report()) newFile.close() with open('fitData.txt', 'r') as inF: for line in inF: if 'gamma:' in line: j = line.split() inF.close() FWHM = float(j[1]) error = float(j[3]) fit = result.best_fit fit = fit.tolist() return FWHM, error, fit I increased the order of polynomial to obtain a better fit for the data and returned the FWHM, its error and the values for the fit. There are likely much better ways of achieving this but the final fit is as I needed. Final fit. Red data points are raw data, the black line is the fitted distribution.
R - Arrays with variable dimension
I have a weird question.. Essentially, I have a function which takes a data frame of dimension Nx(2k) and transforms it into an array of dimension Nx2xk. I then further use that array in various locations in the function. My issue is this, when k == 2, I'm left with a matrix of degree Nx2, and even worse, if N = 1, I'm stuck with a matrix of degree 1x2. I would like to write myArray[thisRow,,] to select that slice of the array, but this falls short for the N = 1, k = 2 case. I tried myArray[thisRow,,,drop = FALSE] but that gives an 'incorrect number of dimensions' error. This same issue arrises for the Nx2 case. Is there a work around for this issue, or do I need to break my code into cases? Sample Code Shown Below: thisFunction <- function(myDF) { nGroups = NCOL(myDF)/2 afMyArray = myDF if(nGroups > 1) { afMyArray = abind(lapply(1:nGroups, function(g){myDF[,2*(g-1) + 1:2]}), along = 3) } sapply(1:NROW(myDF), function(r) { thisSlice = afMyArray[r,,] *some operation on thisSlice* }) } Thanks, James