In Minitab, it is easy to create "cutpoint" histograms. Can this be done in ggplot2?
For example,
df <- data.frame(x = c(0.08, 0.21, 0.25, 0.4, 0.5, 0.6))
ggplot(df, aes(x = x)) + geom_histogram(binwidth = 0.1)
As you can see here, R defaults to "midpoint" histograms. The bar containing the 0.08 is being marked with a bar at the 0.1. The bar containing the 0.21 and 0.25 is being marked at the 0.2 and so forth.
Can I somehow change these bars so the first bar covers the area between 0 and 0.1, and the second bar covers the area between 0.2 and 0.3, and so forth?
You can get rid of the problem in two ways: using parameter "center" or using "boundary". With "center" you can specify the center of one of the bins, "boundary" is similar but you specify the value of a boundary between two bins. Worth noting that "center" and "boundary" can be either above or below the range of the data, in this case the value provided will be shifted of an adequate number of widths.
In this case you already know the width of the bin, its boundaries, so with this parameters you can easily do what you asked:
library(ggplot2)
df <- data.frame(x = c(0.08, 0.21, 0.25, 0.4, 0.5, 0.6))
# This is "center" solution:
ggplot(df, aes(x = x)) + geom_histogram(binwidth = 0.1, center=0.05)
# This is with "boundary" parameter
ggplot(df, aes(x = x)) + geom_histogram(binwidth = 0.1, boundary=0.1)
You can find details and more information on the reference ?geom_histogram.
Hope this helps
Related
I have plotted a bar graph with values smaller than 1 and combined it with two lines, one with positive and the other with negative larger values. When I plot it, the bar lines are much smaller and difficult to see. I would like to change the scale of the Y axis so that the bars that go from 0 to 0.5 are seen bigger. The objective would be to try to break the y axis in 2, from 0 to 0.5 and the rest. I thought about applying log = "y" to barplot, but the axis goes from negative to positive and cannot be logged. (Error in barplot.default(data$bv, data$year, ylim = c(-3, 3), log = "y") : log scale error: at least one 'height + offset' value <= 0 ). Any ideas about how to solve this?
data <- data.frame(c(2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018))
data$bv <- as.numeric(c(0.29,-0.15,0.1, 0.3, 0.2, -0.1, 0.25, -0.2, -0.3,0.08,-0.54, -0.24, -0.15, 0.26, 0.12, 0.23,-0.16,0.3))
data$pvp <- as.numeric(rep(c(2.8,2.9,3),times=6))
data$pvn <- as.numeric(rep(c(-2.8,-2.9,-3),times=6))
data$year <- as.numeric(c(2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018))
bar <- barplot(data$bv, data$year, ylim=c(-3,3))
par(new = T)
plot(data$pvp,ylim=c(-3,3),axes=F,xlab="",ylab="",type="b",lty=3,lwd=1.5,pch=15,cex=0.8)
points(data$pvn,type="b",lty=3,lwd=1.5,pch=17,cex=0.8)
You could take the log of the absolute value, then multiply that by the sign of the original value:
data$bv <- log(abs(data$bv)) * sign(data$bv)
Which gives you this:
I have got a graph like below, except without the red and blue indifference curves (level sets). I know I can use contour() but that creates long curves going from edge to edge.
Is there any way I can create such curves? They don't have to follow a function or any data in particular, I just wanna show the general picture.
You can try with contour
sig <- seq(0,0.25,by=.01)
exr <- seq(0,.20,length.out = length(sig))
# define function
Uf=function(sig,ret,ra=1)ret-0.5*(1/ra)*sig^2
u = outer(sig,exr,function(sd,mr)Uf(sd,mr,ra=0.075))
#image(sig,exr,u)
#contour(sig,exr,u)
contour(sig,exr,u, levels =c(0.04666667, 0.07500000, 0.10333333),col=3,drawlabels = F)
v = outer(sig,exr,function(sd,mr)Uf(sd,mr,ra=0.195))
contour(sig,exr,v, levels =c(0.07333333, 0.09500000, 0.11666667),add = T,col=4,drawlabels = F)
abline(a=0.03,b=0.6666667)
Edit
Uf is a classical quadratic preference function that depends on risk, return and risk aversion. See more information for example here.
outer fist make all possible combination of the supplied vectors sig and exr, then takes every pair of values and computes the utility with Uf. Try head(u) or View(u).
contour takes all values to plot with the desired levels (indifference curves).
abline adds a reference line that you actually have in your plot.
A handmade solution requiring some fiddling with the position and the curvature:
line <- data.frame(x = 0, xend = 0.2, y = 0.03, yend = 0.18)
ggplot(line, aes(x, y, xend=xend, yend=yend)) +
geom_segment() +
annotate(
"curve",
x = 0.02 - c(0, 0.005, 0.01),
y = 0.08 + c(0, 0.01, 0.02),
xend = 0.08 - c(0, 0.005, 0.01),
yend = 0.14 + c(0, 0.01, 0.02),
color = "red", curvature=0.76) +
expand_limits(y = 0)
I want a lattice barchart that looks like ggplot barchart with reverse y axis from here
http://www.sthda.com/english/wiki/ggplot2-rotate-a-graph-reverse-and-flip-the-plot
In other words, I want to turn the barchart in lattice upside down, with the origin of bars at the top. I looked for the solution for quite some time thinking it should be easy, yet failed to find one...
require(lattice)
data <- data.frame(y = c(0.1, 0.4, 0.3, 0.23, 0.17, 0.27), x = c(1,2,3,4,5,6))
histogram <- barchart(data$y ~ data$x, horizontal = FALSE)
histogram
The code above produces regular barchart. What I want to do is to make bars start from the top, not from the bottom, with y scale reversed. In other words, I want this exact graph, but upside down.
Here's one trick to do that:
plot the -y instead of y, and specify that the origin is 0, then you can change the labels on the y axis as you see fit
mydata <- data.frame(y = c(0.1, 0.4, 0.3, 0.23, 0.17, 0.27), x = c(1,2,3,4,5,6))
# fix where you want the ticks to be
ticks_at <- seq(-0.5, 0, 0.1)
barchart(-y ~ x,
mydata,
horizontal = FALSE,
origin=0,
# set the position of the ticks and their labels
scales = list(y=list(at = ticks_at,
labels = -1 * (ticks_at))),
xlab = "x-Axis",
ylab ="y-Axis")
You'll get something like this :
I want to figure out how to build complex curved lines/polygons in R. We can easily draw a simple bezier line, e.g.
require(grid)
x <- c(0.25, 0.25, 0.75, 0.75)
y <- c(0.25, 0.75, 0.75, 0.25)
grid.newpage()
grid.bezier(x, y)
This method seems scale-constrained to 0-1 in both axes, and I'm not sure how to build beziers in a custom scale. I'm also unclear how R can bind these bezier objects together into polylines and ultimately polygons. If anyone can provide a minimal example I'd be very grateful. But alternatively a point in the right direction of documentation would greatly help, as I've not found a workflow so far. Thanks in advance.
As far as I understand grid.bezier you will have to chain individuals segments. This can be done via the id argument, but see also ?grig.bezier.
You can adjust the scale through viewports and the xscale and yscale.
library(grid)
x <- c(0.2, 0.2, 0.7, 0.4, 0.2, 0.2, 0.4, 0.4)
y <- c(0.2, 0.4, 0.7, 0.2, 0.2, 0, 0, 0.2)
grid.newpage()
grid.bezier(x, y, id=rep(1:2, each=4))
grid.newpage()
pushViewport(plotViewport(xscale=c(0, 10), yscale=c(0, 100)))
grid.xaxis()
grid.yaxis()
x <- x * 10
y <- y * 50
grid.bezier(x, y, id=rep(1:2, each=4), default.units="native")
Note that I used dataViewport which is just a convenience function wrapping viewport.
If you have the parametrization 'Y' of the curve you want to draw, you could just
t <- c(1:1000)*0.001
plot(t,Y(t))
or something like that.
I'm fairly new to R so please comment on anything you see.
I have data taken at different timepoints, under two conditions (for one timpoint) and I want to plot this as a bar plot with errorbars and with the bars at the appropriate timepoint.
I currently have this (stolen from another question on this site):
library(ggplot2)
example <- data.frame(tp = factor(c(0, "14a", "14b", 24, 48, 72)), means = c(1, 2.1, 1.9, 1.8, 1.7, 1.2), std = c(0.3, 0.4, 0.2, 0.6, 0.2, 0.3))
ggplot(example, aes(x = tp, y = means)) +
geom_bar(position = position_dodge()) +
geom_errorbar(aes(ymin=means-std, ymax=means+std))
Now my timepoints are a factor, but the fact that there is an unequal distribution of measurements across time makes the plot less nice.!
This is how I imagine the graph :
I find the ggplot2 package can give you very nice graphs, but I have a lot more difficulty understanding it than I have with other R stuff.
Before we get into R, you have to realize that even in a bar plot the x axis needs a numeric value. If you treat them as factors then the software assumes equal spacing between the bars by default. What would be the x-values for each of the bars in this case? It can be (0, 14, 14, 24, 48, 72) but then it will plot two bars at point 14 which you don't seem to want. So you have to come up with the x-values.
Joran provides an elegant solution by modifying the width of the bars at position 14. Modifying the code given by joran to make the bars fall at the right position in the x-axis, the final solution is:
library(ggplot2)
example <- data.frame(tp = factor(c(0, "14a", "14b", 24, 48, 72)), means = c(1, 2.1, 1.9, 1.8, 1.7, 1.2), std = c(0.3, 0.4, 0.2, 0.6, 0.2, 0.3))
example$tp1 <- gsub("a|b","",example$tp)
example$grp <- c('a','a','b','a','a','a')
example$tp2 <- as.numeric(example$tp1)
ggplot(example, aes(x = tp2, y = means,fill = grp)) +
geom_bar(position = "dodge",stat = "identity") +
geom_errorbar(aes(ymin=means-std, ymax=means+std),position = "dodge")