I want to plot a curve that has a change point at x=5
Until now I am using the code
curve(exp(0.68+0.92*x), from=0,to=5, xlim=c(0,12), ylim=c(0,500))
curve(exp(0.68+0.92*x-0.7*(x-5)), from=5,to=12, add=T)
Is it possible to write it in one line (one curve command)? I was thinking
something like this
curve(exp(0.47+0.8*x-0.7*(x-5)*if(x<5,0,1)), from=0,to=12, xlim=c(0,12), ylim=c(0,500))
but it doesn't work for R
Using ifelse you can create one data series:
values = ifelse(x <= 5, exp(0.68+0.92*x), exp(0.68+0.92*x-0.7*(x-5))
and plot them:
curve(values)
and if you insist on a one-liner you can combine the ifelse and the call to curve:
curve(ifelse(x <= 5, exp(0.68+0.92*x), exp(0.68+0.92*x-0.7*(x-5)))
although separating the code into two lines makes it easier to read imo.
You could just write a function that plots both curves:
myfun <- function(...) {
plot(...)
lines(...)
}
You have to give the right arguments of course. The result is two curves in one plot
Related
when using the "curve" function in R, how do you suppress/stop the plot from showing up? For example, this code always plots the curve
my_curve = curve(x)
Is there a parameter to do this or should I being using a different function? I just want the x y points as a dataframe from the curve.
curve() is from the graphics library and is unhandy for generating lists.
Just try using:
x = seq(from, to, length.out = n)
y = function(x)
If you stick to the curve function, the closest to a solution I know is adding dev.off() after the curve() statement!
Here's a way to take advantage of the part of curve that you want without generating a plot.
I made a copy of the curve function (just type curve in the console); called it by a new name (curve2); and commented out the four lines at the end starting with if (isTRUE(add)). When it's called and assigned, I had a list with two vectors—x and y. No plot.
there
I am new on R. I want to plot a graph like this.
The curves are created by these equations :
(log(0.4)-(0.37273*log(x)-1.79389))/0.17941
(log(0.5)-(0.37273*log(x)-1.79389))/0.17941
(log(0.6)-(0.37273*log(x)-1.79389))/0.17941
etc. The equations are similar, the only difference is the first log(XXX). I already manually draw the graph by repeating plot() for each equation.
But I think there must be a way to just assign a simple variable like
x<-c(0.4,0.5,0.6,0.7)
and then plot all the curves automatically. I tried to use data frame to make a set of equations, but failed.
You can create a function-generating function and then loop over values of interest. For example
# takes a value, returns a function
logfn <- function(b) {
function(x) (log(b)-(0.37273*log(x)-1.79389))/0.17941
}
x <- c(0.4,0.5,0.6,0.7)
# empty plot
plot(0,0,type="n", ylim=c(-5,5), xlim=c(1,8), xlab="Lenght", ylab="Z-score")
# add plots for questions with `curve()`
for(v in x) {
curve(logfn(v)(x),add=T)
}
I'm looking for some technique in R similiar to command hold all in Matlab.
In Matlab I generate some data:
x = normrnd(0,1,1000,1);
[a,b]=hist(x,20);
L=b(2)-b(1);
area=sum(L*a);
frequency=a/area;
bar(b,frequency,1);
hold all;
range=b(1):0.1:b(20);
f1=normpdf(range,0,1);
f2=normpdf(range,2,2);
plot1=plot(range,f1,'r');
plot2=plot(range,f2,'m');
hold off;
I would like to create something similiar in R. I've tried this way:
x <- rnorm(1000)
h <- hist(x, breaks = 20)
a <- h$counts
b <- h$mids
L <- b[2] - b[1]
area <- sum(L*a)
frequency = a/area
range <- seq(b[1],b[20], by = 0.1)
f1 <- dnorm(range,0,1)
f2 <- dnorm(range,2,2)
barplot(frequency, names.arg = c(b))
And I stopped here, since I don't know how to add another graph to current plot. I tried to use ggplot2, but I haven't much experience with that and I failed on creating barplot with this library.
If there is a way to do that with ggplot2, I would like to know it with explanation, since I want to learn it. I will appreciate solution with traditional plot system aswell.
P.S. I used barplot(frequency, names.arg = c(b)), because I read here, that there is no equivalent in R for Matlab's bar function.
Sometimes it is better to tell us what you are trying to do, rather than how you are trying to do it. From the looks of your R code your boxplot is just a scaled histogram and from the other R code and my guesses from the matlab code you want to add reference lines for normal distributions. If I am correct then you are going about this the long way in R. The following R code is much simpler:
x <- rnorm(1000)
hist(x, prob=TRUE)
curve(dnorm(x,0,1), add=TRUE)
curve(dnorm(x,2,2), add=TRUE)
Even better would be to add col='blue' or similar to the curve calls. If you really feel the need to choose your own x values then you can replace the calls to curve with:
lines(range, dnorm(range, 0, 1) )
lines(range, dnorm(range, 2, 2) )
If you really want to learn to add lines to a barplot then you should realize that the default locations for bars may not be what you expect. Look at the updateusr function in the TeachingDemos package for R for examples of adding lines to a barplot.
I have been trying to plot simple density plots using R as:
plot(density(Data$X1),col="red")
plot(density(Data$X2),col="green")
Since I want to compare, I'd like to plot both in one figure. But 'matplot' doesn't work!! I also tried with ggplot2 as:
library(ggplot2)
qplot(Data$X1, geom="density")
qplot(Data$X2, add = TRUE, geom="density")
Also in this case, plots appear separately (though I wrote add=TRUE)!! Can anyone come up with an easy solution to the problem, please?
In ggplot2 or lattice you need to reshape the data to seupose them.
For example :
dat <- data.frame(X1= rnorm(100),X2=rbeta(100,1,1))
library(reshape2)
dat.m <- melt(dat)
Using ``lattice`
densityplot(~value , groups = variable, data=dat.m,auto.key = T)
Using ``ggplot2`
ggplot(data=dat.m)+geom_density(aes(x=value, color=variable))
EDIT add X1+X2
Using lattice and the extended formua interface, it is extremely easy to do this:
densityplot(~X1+X2+I(X1+X2) , data=dat) ## no need to reshape data!!
You can try:
plot(density(Data$X1),col="red")
points(density(Data$X2),col="green")
I must add that the xlim and ylim values should ideally be set to include ranges of both X1 and X2, which could be done as follows:
foo <- density(Data$X1)
bar <- density(Data$X2)
plot(foo,col="red", xlim=c(min(foo$x,bar$x),max(foo$x,bar$x)) ylim=c(min(foo$y,bar$y),max(foo$y,bar$y))
points(bar,col="green")
In base graphics you can overlay density plots if you keep the ranges identical and use par(new=TRUE) between them. I think add=TRUE is a base graphics strategy that some functions but not all will honor.
If you specify n, from, and to in the calls to density and make sure that they match between the 2 calls then you should be able to use matplot to plot both in one step (you will need to bind the 2 sets of y values into a single matrix).
I've generated a set of levels from my dataset, and now I want to find a way to sum the rest of the data columns in order to plot it while plotting my first column. Something like:
levelSet <- cut(frame$x1, "cutting")
boxplot(frame$x1~levelSet)
for (l in levelSet)
{
x2Sum<-sum(frame$x2[levelSet==l])
}
or maybe the inside of the loop should look like:
lines(sum(frame$x2[levelSet==l]))
Any thoughts? I am new to R, but I can't seem to get a hang of the indexing and ~ notation thus far.
I know r doesn't work this way, but I'd like functionality that 'looks' like
hist(frame$x2~levelSet)
## Or
hist(frame$x2, breaks = levelSet)
To plot a histograph, boxplot, etc. over a level set:
Try the lattice package:
library(lattice)
histogram(~x2|equal.count(x1),data=frame)
Substitute shingle for equal.count to set your own break points.
ggplot2 would also work nicely for this.
To put a histogram over a boxplot:
par(mfrow=c(2,1))
hist(x2)
boxplot(x2)
You can also use the layout() command to fine-tune the arrangement.