I'm somewhat new to R and I love ggplot - that's all I use for plotting, so I don't know all the archaic syntax needed for base plots in R (and I'd rather not have learn it). I'm running pROC::roc and I would like to plot the output in ggplot (so I can fine tune how it looks). I can immediately get a plot as follows:
size <- 100
response <- sample(c(0,1), replace=TRUE, size=size)
predictor <- rnorm(100)
rocobject <- pROC::roc(response, predictor,smooth=T)
plot(rocobject)
To use ggplot instead, I can create a data frame from the output and then use ggplot (this is NOT my question). What I want to know is if I can somehow 'convert' the plot made in the code above into ggplot automatically so that I can then do what I want in ggplot? I've searched all over and I can't seem to find the answer to this 'basic' question. Thanks!!
Better late than never? I think the ggplotify package might do what you want. You basically plug in your plot generating code to the as.ggplot() function like so:
p6 <- as.ggplot(~plot(iris$Sepal.Length, iris$Sepal.Width, col=color, pch=15))
https://cran.r-project.org/web/packages/ggplotify/vignettes/ggplotify.html
No, I think unfortunately this is not possible.
Even though this does not answer your real question, building it with ggplot is actually not difficult.
Your original plot:
plot(rocobject)
In ggplot:
library(ggplot2)
df<-data.frame(y=unlist(rocobject[1]), x=unlist(rocobject[2]))
ggplot(df, aes(x, y)) + geom_line() + scale_x_reverse() + geom_abline(intercept=1, slope=1, linetype="dashed") + xlab("Specificity") + ylab("sensitivity")
Related
I found this on the Tidyverse Github:
https://github.com/tidyverse/ggplot2/issues/3716
but I can't find the resolution of yutannihilation's question.
For exploratory data analysis, I would like for the outline stroke to reach the x-axis as it does with base R, including facets with scales="free".
Is there a way to do this programmatically? The user may have multiple facets of data, on the same or different scales. Can I ensure the x-axis is wide enough to take the density to zero?
I have tried outline.type = "full" and "both" but neither seem to work.
The MRE shows the issue. The use case is within a Shiny app and can be facet_wrap-ed as well.
Thanks!
#R base
plot(density(diamonds$carat, adjust = 5))
#ggplot
library(ggplot2)
ggplot(diamonds, aes(carat)) +
geom_density(adjust = 5)
A straightforward solution would be to calculate the density yourself and plot that:
library(ggplot2)
ggplot(as.data.frame(density(diamonds$carat, adjust = 5)[1:2]), aes(x, y)) +
geom_line()
I'm using ggplot as described here
Smoothed density estimates
and entered in the R console
m <- ggplot(movies, aes(x = rating))
m + geom_density()
This works but is there some way to remove the connection between the x-axis and the density plot (the vertical lines which connect the density plot to the x-axis)
The most consistent way to do so is (thanks to #baptiste):
m + stat_density(geom="line")
My original proposal was to use geom_line with an appropriate stat:
m + geom_line(stat="density")
but it is no longer recommended since I'm receiving reports it's not universally working for every case in newer versions of ggplot.
The suggested answers dont provide exactly the same results as geom_density. Why not draw a white line over the baseline?
+ geom_hline(yintercept=0, colour="white", size=1)
This worked for me.
Another way would be to calculate the density separately and then draw it. Something like this:
a <- density(movies$rating)
b <- data.frame(a$x, a$y)
ggplot(b, aes(x=a.x, y=a.y)) + geom_line()
It's not exactly the same, but pretty close.
I'm using ggplot as described here
Smoothed density estimates
and entered in the R console
m <- ggplot(movies, aes(x = rating))
m + geom_density()
This works but is there some way to remove the connection between the x-axis and the density plot (the vertical lines which connect the density plot to the x-axis)
The most consistent way to do so is (thanks to #baptiste):
m + stat_density(geom="line")
My original proposal was to use geom_line with an appropriate stat:
m + geom_line(stat="density")
but it is no longer recommended since I'm receiving reports it's not universally working for every case in newer versions of ggplot.
The suggested answers dont provide exactly the same results as geom_density. Why not draw a white line over the baseline?
+ geom_hline(yintercept=0, colour="white", size=1)
This worked for me.
Another way would be to calculate the density separately and then draw it. Something like this:
a <- density(movies$rating)
b <- data.frame(a$x, a$y)
ggplot(b, aes(x=a.x, y=a.y)) + geom_line()
It's not exactly the same, but pretty close.
I would like to plot an INDIVIDUAL box plot for each unrelated column in a data frame. I thought I was on the right track with boxplot.matrix from the sfsmsic package, but it seems to do the same as boxplot(as.matrix(plotdata) which is to plot everything in a shared boxplot with a shared scale on the axis. I want (say) 5 individual plots.
I could do this by hand like:
par(mfrow=c(2,2))
boxplot(data$var1
boxplot(data$var2)
boxplot(data$var3)
boxplot(data$var4)
But there must be a way to use the data frame columns?
EDIT: I used iterations, see my answer.
You could use the reshape package to simplify things
data <- data.frame(v1=rnorm(100),v2=rnorm(100),v3=rnorm(100), v4=rnorm(100))
library(reshape)
meltData <- melt(data)
boxplot(data=meltData, value~variable)
or even then use ggplot2 package to make things nicer
library(ggplot2)
p <- ggplot(meltData, aes(factor(variable), value))
p + geom_boxplot() + facet_wrap(~variable, scale="free")
From ?boxplot we see that we have the option to pass multiple vectors of data as elements of a list, and we will get multiple boxplots, one for each vector in our list.
So all we need to do is convert the columns of our matrix to a list:
m <- matrix(1:25,5,5)
boxplot(x = as.list(as.data.frame(m)))
If you really want separate panels each with a single boxplot (although, frankly, I don't see why you would want to do that), I would instead turn to ggplot and faceting:
m1 <- melt(as.data.frame(m))
library(ggplot2)
ggplot(m1,aes(x = variable,y = value)) + facet_wrap(~variable) + geom_boxplot()
I used iteration to do this. I think perhaps I wasn't clear in the original question. Thanks for the responses none the less.
par(mfrow=c(2,5))
for (i in 1:length(plotdata)) {
boxplot(plotdata[,i], main=names(plotdata[i]), type="l")
}
I've been experimenting with both ggplot2 and lattice to graph panels of data. I'm having a little trouble wrapping my mind around the ggplot2 model. In particular, how do I plot a scatter plot with two sets of data on each panel:
in lattice I could do this:
xyplot(Predicted_value + Actual_value ~ x_value | State_CD, data=dd)
and that would give me a panel for each State_CD with each column
I can do one column with ggplot2:
pg <- ggplot(dd, aes(x_value, Predicted_value)) + geom_point(shape = 2)
+ facet_wrap(~ State_CD) + opts(aspect.ratio = 1)
print(pg)
What I can't grok is how to add Actual_value to the ggplot above.
EDIT Hadley pointed out that this really would be easier with a reproducible example. Here's code that seems to work. Is there a better or more concise way to do this with ggplot? Why is the syntax for adding another set of points to ggplot so different from adding the first set of data?
library(lattice)
library(ggplot2)
#make some example data
dd<-data.frame(matrix(rnorm(108),36,3),c(rep("A",24),rep("B",24),rep("C",24)))
colnames(dd) <- c("Predicted_value", "Actual_value", "x_value", "State_CD")
#plot with lattice
xyplot(Predicted_value + Actual_value ~ x_value | State_CD, data=dd)
#plot with ggplot
pg <- ggplot(dd, aes(x_value, Predicted_value)) + geom_point(shape = 2) + facet_wrap(~ State_CD) + opts(aspect.ratio = 1)
print(pg)
pg + geom_point(data=dd,aes(x_value, Actual_value,group=State_CD), colour="green")
The lattice output looks like this:
(source: cerebralmastication.com)
and ggplot looks like this:
(source: cerebralmastication.com)
Just following up on what Ian suggested: for ggplot2 you really want all the y-axis stuff in one column with another column as a factor indicating how you want to decorate it. It is easy to do this with melt. To wit:
qplot(x_value, value,
data = melt(dd, measure.vars=c("Predicted_value", "Actual_value")),
colour=variable) + facet_wrap(~State_CD)
Here's what it looks like for me:
(source: princeton.edu)
To get an idea of what melt is actually doing, here's the head:
> head(melt(dd, measure.vars=c("Predicted_value", "Actual_value")))
x_value State_CD variable value
1 1.2898779 A Predicted_value 1.0913712
2 0.1077710 A Predicted_value -2.2337188
3 -0.9430190 A Predicted_value 1.1409515
4 0.3698614 A Predicted_value -1.8260033
5 -0.3949606 A Predicted_value -0.3102753
6 -0.1275037 A Predicted_value -1.2945864
You see, it "melts" Predicted_value and Actual_value into one column called value and adds another column called variable letting you know what column it originally came from.
Update: several years on now, I almost always use Jonathan's method (via the tidyr package) with ggplot2. My answer below works in a pinch, but gets tedious fast when you have 3+ variables.
I'm sure Hadley will have a better answer, but - the syntax is different because the ggplot(dd,aes()) syntax is (I think) primarily intended for plotting just one variable. For two, I would use:
ggplot() +
geom_point(data=dd, aes(x_value, Actual_value, group=State_CD), colour="green") +
geom_point(data=dd, aes(x_value, Predicted_value, group=State_CD), shape = 2) +
facet_wrap(~ State_CD) +
theme(aspect.ratio = 1)
Pulling the first set of points out of the ggplot() gives it the same syntax as the second. I find this easier to deal with because the syntax is the same and it emphasizes the "Grammar of Graphics" that is at the core of ggplot2.
you might just want to change the form of your data a little bit, so that you have one y-axis variable, with an additional factor variable indicating whether it is a predicted or actual variable.
Is this something like what you are trying to do?
dd<-data.frame(type=rep(c("Predicted_value","Actual_value"),20),y_value=rnorm(40),
x_value=rnorm(40),State_CD=rnorm(40)>0)
qplot(x_value,y_value,data=dd,colour=type,facets=.~State_CD)
well after posting the question I ran across this R Help thread that may have helped me. It looks like I can do this:
pg + geom_line(data=dd,aes(x_value, Actual_value,group=State_CD), colour="green")
is that a good way of doing things? It odd to me because adding the second item has a totally different syntax than the first.