I have a set of UNIX timestamps and URIs and I'm trying to plot the cumulative count of requests for each URI. I managed to do that for one URI at a time using a dummy column:
x.df$count <- apply(x.df,1,function(row) 1) # Create a dummy column for cumsum
x.df <- x.df[order(x.df$time, decreasing=FALSE),] # Sort
ggplot(x.df, aes(x=time, y=cumsum(count))) + geom_line()
However, that would make roughly 30 plots in my case.
ggplot2 does allow you to plot multiple lines into one plot (I copied this piece of code from here):
ggplot(data=test_data_long, aes(x=date, y=value, colour=variable)) +
geom_line()
The problem is that, this way, cumsum() would count on and on.
Does anybody have an idea?
Here's a test data which uses plyr's transform to calculate the cumulative sum first and then apply that data to plot using ggplot2:
set.seed(45)
DF <- data.frame(grp = factor(rep(1:5, each=10)), x=rep(1:10, 5))
DF <- transform(DF, y=runif(nrow(DF)))
# use plyr to calculate cumsum per group of x
require(plyr)
DF.t <- ddply(DF, .(grp), transform, cy = cumsum(y))
# plot
require(ggplot2)
ggplot(DF.t, aes(x=x, y=cy, colour=grp, group=grp)) + geom_line()
Related
Taking some generic data
A <- c(1997,2000,2000,1998,2000,1997,1997,1997)
B <- c(0,0,1,0,0,1,0,0)
df <- data.frame(A,B)
counts <- t(table(A,B))
frac <- counts[1,]/(counts[2,]+counts[1,])
C <- c(1998,2001,2000,1995,2000,1996,1998,1999)
D <- c(1,0,1,0,0,1,0,1)
df2 <- data.frame(C,D)
counts2 <- t(table(C,D))
frac2 <- counts2[1,]/(counts2[2,]+counts2[1,])
If we then want to create a scatterplot for the two datasets on the one scale
We can:
plot(frac, pch=22)
points(frac2, pch=19)
But we see we have two problems
first we want to put our year values (which appear as df$A and df$C) along the x axis
We want the x axis to automatically adjust the scale when the second data is added.
A solution using ggplot2 or base R would be desired
ggplot will do the scaling for you. You can convert the fracs to data.frame and to use with ggplot
library(ggplot2)
ggplot(data.frame(y=frac, x=names(frac)), aes(x, y)) +
geom_point(col="salmon") +
geom_point(data=data.frame(y=frac2, x=names(frac2)), aes(x, y), col="steelblue") +
theme_bw()
I have a task and i need to plot graph using ggplot2.
I have a vector of rating (Samsung S4 ratings from its users)
I generate this data using this:
TestRate<- data.frame (rating=sample (x =1:5, size=100, replace=T ), month= sample(x=1:12,size=100,rep=T) )
And now I need to plot a graph, where on X axis will be dates (monthes in our example data) and 5 different lines grouped by 5 different ratings (1,2,3,4,5). Each line shows count of its ratings for corresponding month
How can I plot this in ggplot2?
You need first to count the number of elements per couple of (rating, month):
library(data.table)
setDT(TestRate)[,count:=.N,by=list(month, rating)]
And then you can plot the result:
ggplot(TestRate, aes(month, count, color=as.factor(rating))) + geom_line()
If your data.table is not set (so to speak), you can use dplyr (and rename the legend while you are at it).
df <- TestRate %>% group_by(rating, month) %>% summarise(count = n())
ggplot(df, aes(x=month, y=count, color=as.factor(rating))) + geom_line() + labs(color = "Rating")
I am trying to plot the following data
factor <- as.factor(c(1,2,3))
V1_mean <- c(100,200,300)
V2_mean <- c(350,150,60)
V1_stderr <- c(5,9,3)
V2_stderr <- c(12,9,10)
plot <- data.frame(factor,V1_mean,V2_mean,V1_stderr,V2_stderr)
I want to create a plot with factor on the x-axis, value on the y-axis and seperate lines for V1 and V2 (hence the points are the values of V1_mean on one line and V2_mean on the other). I would also like to add error bars for these means based on V1_stderr and V2_stderr
Many thanks
I'm not sure regarding your desired output, but here's a possible solution.
First of all, I wouldn't call your data plot as this is a stored function in R which is being commonly used
Second of all, when you want to plot two lines in ggplot you'll usually have to tide your data using functions such as melt (from reshape2 package) or gather (from tidyr package).
Here's an a possible approach
library(ggplot2)
library(reshape2)
dat <- data.frame(factor, V1_mean, V2_mean, V1_stderr, V2_stderr)
mdat <- cbind(melt(dat[1:3], "factor"), melt(dat[c(1, 4:5)], "factor"))
names(mdat) <- make.names(names(mdat), unique = TRUE)
ggplot(mdat, aes(factor, value, color = variable)) +
geom_point(aes(group = variable)) + # You can also add `geom_point(aes(group = variable)) + ` if you want to see the actual points
geom_errorbar(aes(ymin = value - value.1, ymax = value + value.1))
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",])
I would like some help coloring a ggplot2 histogram generated from already-summarized count data.
The data are something like counts of # males and # females living in a number of different areas. It's easy enough to plot the histogram for the total counts (i.e. males + females):
set.seed(1)
N=100;
X=data.frame(C1=rnbinom(N,15,0.1), C2=rnbinom(N,15,0.1),C=rep(0,N));
X$C=X$C1+X$C2;
ggplot(X,aes(x=C)) + geom_histogram()
However, I'd like to color each bar according to the relative contribution from C1 and C2, so that I get the same histogram (i.e. overall bar heights) as in the above example, plus I see the proportion of type "C1" and "C2" individuals as in a stacked bar chart.
Suggestions for a clean way to do this with ggplot2, using data like "X" in the example?
Very quickly, you can do what the OP wants using the stat="identity" option and the plyr package to manually calculate the histogram, like so:
library(plyr)
X$mid <- floor(X$C/20)*20+10
X_plot <- ddply(X, .(mid), summarize, total=length(C), split=sum(C1)/sum(C)*length(C))
ggplot(data=X_plot) + geom_histogram(aes(x=mid, y=total), fill="blue", stat="identity") + geom_histogram(aes(x=mid, y=split), fill="deeppink", stat="identity")
We basically just make a 'mids' column for how to locate the columns and then make two plots: one with the count for the total (C) and one with the columns adjusted to the count of one of the columns (C1). You should be able to customize from here.
Update 1: I realized I made a small error in calculating the mids. Fixed now. Also, I don't know why I used a 'ddply' statement to calculate the mids. That was silly. The new code is clearer and more concise.
Update 2: I returned to view a comment and noticed something slightly horrifying: I was using sums as the histogram frequencies. I have cleaned up the code a little and also added suggestions from the comments concerning the coloring syntax.
Here's a hack using ggplot_build. The idea is to first get your old/original plot:
p <- ggplot(data = X, aes(x=C)) + geom_histogram()
stored in p. Then, use ggplot_build(p)$data[[1]] to extract the data, specifically, the columns xmin and xmax (to get the same breaks/binwidths of histogram) and count column (to normalize the percentage by count. Here's the code:
# get old plot
p <- ggplot(data = X, aes(x=C)) + geom_histogram()
# get data of old plot: cols = count, xmin and xmax
d <- ggplot_build(p)$data[[1]][c("count", "xmin", "xmax")]
# add a id colum for ddply
d$id <- seq(nrow(d))
How to generate data now? What I understand from your post is this. Take for example the first bar in your plot. It has a count of 2 and it extends from xmin = 147 to xmax = 156.8. When we check X for these values:
X[X$C >= 147 & X$C <= 156.8, ] # count = 2 as shown below
# C1 C2 C
# 19 91 63 154
# 75 86 70 156
Here, I compute (91+86)/(154+156)*(count=2) = 1.141935 and (63+70)/(154+156) * (count=2) = 0.8580645 as the two normalised values for each bar we'll generate.
require(plyr)
dd <- ddply(d, .(id), function(x) {
t <- X[X$C >= x$xmin & X$C <= x$xmax, ]
if(nrow(t) == 0) return(c(0,0))
p <- colSums(t)[1:2]/colSums(t)[3] * x$count
})
# then, it just normal plotting
require(reshape2)
dd <- melt(dd, id.var="id")
ggplot(data = dd, aes(x=id, y=value)) +
geom_bar(aes(fill=variable), stat="identity", group=1)
And this is the original plot:
And this is what I get:
Edit: If you also want to get the breaks proper, then, you can get the corresponding x coordinates from the old plot and use it here instead of id:
p <- ggplot(data = X, aes(x=C)) + geom_histogram()
d <- ggplot_build(p)$data[[1]][c("count", "x", "xmin", "xmax")]
d$id <- seq(nrow(d))
require(plyr)
dd <- ddply(d, .(id), function(x) {
t <- X[X$C >= x$xmin & X$C <= x$xmax, ]
if(nrow(t) == 0) return(c(x$x,0,0))
p <- c(x=x$x, colSums(t)[1:2]/colSums(t)[3] * x$count)
})
require(reshape2)
dd.m <- melt(dd, id.var="V1", measure.var=c("V2", "V3"))
ggplot(data = dd.m, aes(x=V1, y=value)) +
geom_bar(aes(fill=variable), stat="identity", group=1)
How about:
library("reshape2")
mm <- melt(X[,1:2])
ggplot(mm,aes(x=value,fill=variable))+geom_histogram(position="stack")