I'm trying to make a plot in R from a data frame with several columns and I'd like to have ggplot plot one of the columns as points, and the other several as lines of different colors.
I can find examples about how to make each of these plots separately, but I can't seem to find the command to combine the plots...
Thanks for any help you can provide.
Like this:
dat <- data.frame(points.x = c(1:10), points.y = c(1:10),
lines.x = c(10:1), lines.y = c(1:10))
ggplot(dat, aes(points.x, points.y)) + geom_point() +
geom_line(aes(lines.x,lines.y))
In order to plot several different columns as lines of different colors, use the melt function from the reshape2 package.
For example:
df <- data.frame(A=1:10, B=rnorm(10), C=rnorm(10), D=rnorm(10))
melted <- melt(df, id="A")
ggplot(melted[melted$variable!="B",], aes(A, value, color=variable)) + geom_line() +
geom_point(data=melted[melted$variable=="B",])
Related
My goal is to visualize some data frames with ggplot2.
I have several data.frames looking like this
And my goal is a boxplot looking like this, just nicer.
I managed to get single boxplots using
plt <- ggplot(data, aes(RF, data$RF)) +
geom_boxplot()
plt
But that's not what I want.
library(ggplot2)
library(reshape)
airquality_m = melt(airquality)
ggplot(airquality_m, aes(variable, value )) + geom_boxplot()
I did not beautify the plot but I guess you get the idea here.
That boxplot you showed is created with base-r graphics. Single command
boxplot(data) will do it.
If you want to use ggplot, you have to first melt the dataframe and then plot.
library(reshape2)
datPlot <- melt(data)
ggplot(datPlot,aes(variable,value)) + geom_boxplot()
I guess this is what you want:
library(ggplot2)
library(reshape)
myddt_m = melt(mydata)
names(myddt_m)=c("Models","CI")
ggplot(myddt_m, aes(Models, CI,fill=Models )) + geom_boxplot()+guides(fill=FALSE)+labs( x="", y="C-Index")
The whole dataset describes a module (or cluster if you prefer).
In order to reproduce the example, the dataset is available at:
https://www.dropbox.com/s/y1905suwnlib510/example_dataset.txt?dl=0
(54kb file)
You can read as:
test_example <- read.table(file='example_dataset.txt')
What I would like to have in my plot is this
On the plot, the x-axis is my Timepoints column, and the y-axis are the columns on the dataset, except for the last 3 columns. Then I used facet_wrap() to group by the ConditionID column.
This is exactly what I want, but the way I achieved this was with the following code:
plot <- ggplot(dataset, aes(x=Timepoints))
plot <- plot + geom_line(aes(y=dataset[,1],colour = dataset$InModule))
plot <- plot + geom_line(aes(y=dataset[,2],colour = dataset$InModule))
plot <- plot + geom_line(aes(y=dataset[,3],colour = dataset$InModule))
plot <- plot + geom_line(aes(y=dataset[,4],colour = dataset$InModule))
plot <- plot + geom_line(aes(y=dataset[,5],colour = dataset$InModule))
plot <- plot + geom_line(aes(y=dataset[,6],colour = dataset$InModule))
plot <- plot + geom_line(aes(y=dataset[,7],colour = dataset$InModule))
plot <- plot + geom_line(aes(y=dataset[,8],colour = dataset$InModule))
...
As you can see it is not very automated. I thought about putting in a loop, like
columns <- dim(dataset)[2] - 3
for (i in seq(1:columns))
{
plot <- plot + geom_line(aes(y=dataset[,i],colour = dataset$InModule))
}
(plot <- plot + facet_wrap( ~ ConditionID, ncol=6) )
That doesn't work.
I found this topic
Use for loop to plot multiple lines in single plot with ggplot2 which corresponds to my problem.
I tried the solution given with the melt() function.
The problem is that when I use melt on my dataset, I lose information of the Timepoints column to plot as my x-axis. This is how I did:
data_melted <- dataset
as.character(data_melted$Timepoints)
dataset_melted <- melt(data_melted)
I tried using aggregate
aggdata <-aggregate(dataset, by=list(dataset$ConditionID), FUN=length)
Now with aggdata at least I have the information on how many Timepoints for each ConditionID I have, but I don't know how to proceed from here and combine this on ggplot.
Can anyone suggest me an approach.
I know I could use the ugly solution of creating new datasets on a loop with rbind(also given in that link), but I don't wanna do that, as it sounds really inefficient. I want to learn the right way.
Thanks
You have to specify id.vars in your call to melt.data.frame to keep all information you need. In the call to ggplot you then need to specify the correct grouping variable to get the same result as before. Here's a possible solution:
melted <- melt(dataset, id.vars=c("Timepoints", "InModule", "ConditionID"))
p <- ggplot(melted, aes(Timepoints, value, color = InModule)) +
geom_line(aes(group=paste0(variable, InModule)))
p
What I really want to do is plot a histogram, with the y-axis on a log-scale. Obviously this i a problem with the ggplot2 geom_histogram, since the bottom os the bar is at zero, and the log of that gives you trouble.
My workaround is to use the freqpoly geom, and that more-or less does the job. The following code works just fine:
ggplot(zcoorddist) +
geom_freqpoly(aes(x=zcoord,y=..density..),binwidth = 0.001) +
scale_y_continuous(trans = 'log10')
The issue is that at the edges of my data, I get a couple of garish vertical lines that really thro you off visually when combining a bunch of these freqpoly curves in one plot. What I'd like to be able to do is use points at every vertex of the freqpoly curve, and no lines connecting them. Is there a way to to this easily?
The easiest way to get the desired plot is to just recast your data. Then you can use geom_point. Since you don't provide an example, I used the standard example for geom_histogram to show this:
# load packages
require(ggplot2)
require(reshape)
# get data
data(movies)
movies <- movies[, c("title", "rating")]
# here's the equivalent of your plot
ggplot(movies) + geom_freqpoly(aes(x=rating, y=..density..), binwidth=.001) +
scale_y_continuous(trans = 'log10')
# recast the data
df1 <- recast(movies, value~., measure.var="rating")
names(df1) <- c("rating", "number")
# alternative way to recast data
df2 <- as.data.frame(table(movies$rating))
names(df2) <- c("rating", "number")
df2$rating <- as.numeric(as.character(df$rating))
# plot
p <- ggplot(df1, aes(x=rating)) + scale_y_continuous(trans="log10", name="density")
# with lines
p + geom_linerange(aes(ymax=number, ymin=.9))
# only points
p + geom_point(aes(y=number))
At the moment I`m writing my bachelor thesis and all of my plots are created with ggplot2. Now I need a plot of two ecdfs but my problem is that the two dataframes have different lengths. But by adding values to equalize the length I would change the distribution, therefore my first thought isn't possible. But a ecdf plot with two different dataframes with a different length is forbidden.
daten <- peptidPSMotherExplained[peptidPSMotherExplained$V3!=-1,]
daten <- cbind ( daten , "scoreDistance"= daten$V2-daten$V3 )
daten2 <- peptidPSMotherExplained2[peptidPSMotherExplained2$V3!=-1,]
daten2 <- cbind ( daten2 , "scoreDistance"= daten2$V2-daten2$V3 )
p <- ggplot(daten, aes(x = scoreDistance)) + stat_ecdf()
p <- p + geom_point(aes(x = daten2$lengthDistance))
p
with the normal plot function of R it is possible
plot(ecdf(daten$scoreDistance))
plot(ecdf(daten2$scoreDistance),add=TRUE)
but it looks different to all of my other plots and I dislike this.
Has anybody a solution for me?
Thank you,
Tobias
Example:
df <-data.frame(scoreDifference = rnorm(10,0,12))
df2 <- data.frame(scoreDifference = rnorm(5,-3,9))
plot(ecdf(df$scoreDifference))
plot(ecdf(df2$scoreDifference),add=TRUE)
So how can I achieve this kind of plot in ggplot?
I don't know what geom one should use for such plots, but for combining two datasets you can simply specify the data in a new layer,
ggplot(df, aes(x = scoreDifference)) +
stat_ecdf(geom = "point") +
stat_ecdf(data=df2, geom = "point")
I think, reshaping your data in the right way will probably make ggplot2 work for you:
df <-data.frame(scoreDiff1 = rnorm(10,0,12))
df2 <- data.frame(scoreDiff2 = rnorm(5,-3,9))
library('reshape2')
data <- merge(melt(df),melt(df2),all=TRUE)
Then, with data in the right shape, you can simply go on to plot the stuff with colour (or shape, or whatever you wish) to distinguish the two datasets:
p <- ggplot(daten, aes(x = value, colour = variable)) + stat_ecdf()
Hope this is what you were looking for!?
I'm still pretty new to R, and have come up against a plotting problem I can't find an answer to.
I've got a data frame that looks like this (though a lot bigger):
df <- data.frame(Treatment= rep(c("A", "B", "C"), each = 6),
LocA=sample(1:100, 18),
LocB=sample(1:100, 18),
LocC=sample(1:100, 18))
And I want dot plots that look like this one produced in Excel. It's exactly the formatting I want: a dotplot for each of the treatments side-by-side for each location, with data for multiple locations together on one graph. (Profuse apologies for not being able to post the image here; posting images requires a 10 reputation.)
It's no problem to make a plot for each location, with the dots color-coded, and so on:
ggplot(data = df, aes(x=Treatment, y=LocA, color = Treatment)) + geom_point()
but I can't figure out how to add locations B and C to the same graph.
Any advice would be much appreciated!
As a couple of people have mentioned, you need to "melt" the data, getting it into a "long" form.
library(reshape2)
df_melted <- melt(df, id.vars=c("Treatment"))
colnames(df_melted)[2] <- "Location"
In ggplot jargon, having different groups like treatment side-by-side is achieved through "dodging". Usually for things like barplots you can just say position="dodge" but geom_point seems to require a bit more manual specification:
ggplot(data=df_melted, aes(x=Location, y=value, color=Treatment)) +
geom_point(position=position_dodge(width=0.3))
You need to reshape the data. Here an example using reshape2
library(reshape2)
dat.m <- melt(dat, id.vars='Treatment')
library(ggplot2)
ggplot(data = dat.m,
aes(x=Treatment, y=value,shape = Treatment,color=Treatment)) +
geom_point()+facet_grid(~variable)
Since you want a dotplot, I propose also a lattice solution. I think it is more suitable in this case.
dotplot(value~Treatment|variable,
groups = Treatment, data=dat.m,
pch=c(25,19),
par.strip.text=list(cex=3),
cex=2)