Looping ggplot across many variables - r

############
EDIT
############
I used this info_mat to compute evolution rates.
date1 <- rbind("February", "March", "April", "May", "June", "July", "August", "September", "October", "November")
sum1.visit_bush. <- rbind("0", "0" ,"1" , "-0.75" ,"2","0" ,"0.333333333333333" , "1.25" , "0", "-1")
sum1.counts_bush. <- rbind("0" ,"0.115290451813933", "-0.557273997206146", "0.146270002253775" , "0.100865119937082", "0.512412930880514", "0.435049598488427", "-0.0831961816984858", "0.824791311372408", "-0.156025577963601" )
sum1.hcounts_bush. <- rbind("0", "0.0387010676156584", "-0.625695931477516", "0.47254004576659", "-0.233100233100233", "0.99290780141844" , "-0.032536858159634" , "0.349973725696269" , "0.660957571039315", "-0.341223341926412")
evolution1 <- data.frame(date1, sum1.visit_bush., sum1.counts_bush., sum1.hcounts_bush.)
I then proceed as you suggested
df_month_cand <- evolution1 %>% select(c("date", paste0(c("sum.visit_", "sum.counts_", "sum.hcounts_"), "bush.")))
df_month_cand_plot <- melt(df_month_cand, id.vars = "date", variable.name = "Type", value.name = "y")
FunctionPlot <- function(cand, evolution) {
df_month_cand <- evolution %>% select(c("date1", paste0(c("sum1.visit_", "sum1.counts_", "sum1.hcounts_"), cand)))
df_month_cand_plot <- melt(df_month_cand, id.vars = "date1", variable.name = "Type", value.name = "y")
p <- ggplot(df_month_cand_plot, aes(x = date1, y = y, color = Type)) + geom_point() + geom_line(aes(group=Type)) +
labs(
title = paste0("Evolution of visits and coverage
per month for ", cand) ,
subtitle = "We read: from March to April, whereas the visits of -candidate- increased by -value*100 %-,
the coverage in newspapers decreased by -value*100 %-",
color="Type",
x="Months",
y="Percentage change over months") +
theme(
plot.title = element_text(size=15, face="bold", margin = margin(5, 0, 10, 10), vjust=2, hjust=0.5),
axis.text.x=element_text(angle=50, size=11.5, vjust=0.5),
axis.title.y = element_text(vjust=4),
plot.margin = unit(c(1, 0.3, 0.5, 0.6), "cm"),
legend.position = "bottom",
legend.box.background = element_rect(color="black", size=2),
legend.title = element_text(face = "bold", size=10),
legend.background = element_rect(fill="grey90",
size=0.5, linetype="solid",
colour ="black"),
panel.background = element_rect(fill = "gray90", colour = "gray70", size = 0.5, linetype = "solid"),
panel.grid.major = element_line(size = 0.5, linetype = 'dashed', colour = "gray75")) +
scale_color_manual(labels = c("Visits", "Main text count", "Headline count"), values = c("tomato3", "deepskyblue3", "green2")) +
scale_x_discrete(limits = c("February", "March", "April", "May", "June", "July", "August", "September", "October", "November")) +
scale_y_discrete()
plot(p)
}
sapply("bush.", FunctionPlot, evolution1)
However, on the output the y axis is completely messed-up.
The values are not sorted from least to greatest.
Why? How to resolve this?
Lastly, to simplify the y axis I'd like to divide is from -1 to 2 with breaks of 0.25
I tried
scale_y_continuous(breaks=seq(-1, 2, 0.25))
But I have the following error code:
Error: Discrete value supplied to continuous scale
Thanks!!!!

You can convert you variable date from character to Date format:
date <- as.Date(date, format = "%Y-%d-%m")
ggplot can print dates at X axes. Now you don't need to create variable months by hand.
I think you should work with data.frame:
df_info <- data.frame(
date = date,
a1 = c(0, 0, 0, 0, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
b1 = c(1, 1, 1, 1, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
hb1 = c(2, 2, 2, 2, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
a2 = c(0, 0, 0, 0, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
b2 = c(1, 1, 1, 1, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
hb2 = c(2, 2, 2, 2, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
a3 = c(0, 0, 0, 0, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
b3 = c(1, 1, 1, 1, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
hb3 = c(2, 2, 2, 2, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
a4 = c(0, 0, 0, 0, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
b4 = c(1, 1, 1, 1, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
hb4 = c(2, 2, 2, 2, 6421, 41, 5667, 44, 1178, 0, 1070, 1)
)
Or if you have big data you can convert matrix to data.frame with converting variables to numeric format (but without names).
df_info <- bind_cols(data.frame(date = date), info_mat[,-1] %>% as.data.frame() %>% lapply(as.numeric)) %>% as.data.frame()
Now we can select columns for first individual:
df <- df_info %>% select(c("date", paste0(c("a", "b", "hb"), 1)))
Next we will create data.frame for plot:
df_plot <- melt(df, id.vars = "date", variable.name = "Type", value.name = "y")
Your function for plot is good you can use it for df_plot. Now let's create function for plotting data for fixed number of individual:
f <- function(num, df_info) {
df <- df_info %>% select(c("date", paste0(c("a", "b", "hb"), num)))
df_plot <- melt(df, id.vars = "date", variable.name = "Type", value.name = "y")
p <- ggplot(df_plot, aes(x = date, y = y, color = `Type`)) + geom_point() +
geom_line() +
labs(
title = "Evolution of a and b and c per months",
subtitle = paste0("plot ", num),
color="Type",
x = "Months",
y = "over months"
)
plot(p)
}
Let's apply our function for each number of individual:
sapply(1:4, f, df_info)
Or
sapply(1:4, function(x) f(x, df_info))
But your data has bad scale. You cannot see the difference between 0 and 1 if you have 6421 on the same plot. but I don't know what you want to do with this data and plots.

Related

Why is ggplot only filling in some of my stacked bars and not others?

I'm making a stacked barplot using ggplot, but for some reason, it keeps leaving 2 bars unfilled, despite filling in other ones using the same criteria. Why is it doing this and how can I prevent this from happening?
library(ggplot2)
library(dplyr)
library(scales)
#Code to replicate
data <- tibble(team = factor(c(rep("Team 1", 10), rep("Team 2", 10), rep("Team 3", 10), rep("Team 4", 10)), levels = c("Team 1", "Team 2", "Team 3", "Team 4")),
state = factor(c(rep(c("Won", "Tied",
"Rematch", "Postponed", "Forfeit",
"Lost", "Withdrew", "Ongoing",
"Undetermined", "Unknown"), 4)), levels = c("Won", "Tied",
"Rematch", "Postponed", "Forfeit",
"Lost", "Withdrew", "Ongoing",
"Undetermined", "Unknown")),
count = c(1920, 80, 241, 5, 310, 99, 2, 127, 20, 33,
48, 1, 8, 0, 11, 3, 0, 4, 3, 3,
140, 5, 8, 0, 17, 2, 0, 5, 3, 7,
477, 20, 59, 1, 106, 1, 0, 33, 7, 10))
data <- data %>%
group_by(team) %>%
mutate(percentage = round((count/sum(count, na.rm = TRUE)), 2))
data %>%
ggplot(aes(fill= state, y = percentage, x = team)) +
geom_col(position="stack",width = 0.4) +
coord_flip() +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), limits = c(0, 1)) +
geom_text(aes(label = scales::percent(percentage, accuracy = 1)),
position = position_stack(vjust = .5),
check_overlap = TRUE )
Here's how it looks; the floating 75% and 59% for Team 3 and Team 2, respectively, should be in the salmon color that is used for Teams 4 and 1. I know it's not a typo because I'm using the same title for each.
Change the position argument to fill
data %>%
ggplot(aes(fill= state, y = percentage, x = team)) +
geom_col(position="fill",width = 0.4) +
coord_flip() +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), limits = c(0, 1)) +
geom_text(aes(label = scales::percent(percentage, accuracy = 1)),
position = position_stack(vjust = .5),
check_overlap = TRUE )

ggplot2 Reorder Data that is in minutes:seconds Format

The first five entries (out of twenty) of my dataset:
>head(data)
Name SDC
<chr> <Period>
1 Feuerman 1M 37S
2 Solis 1M 52S
3 Osborne 1M 47S
4 Frizzell 1M 58S
5 Moran 1M 59S
Also:
> dput(head(data))
structure(list(Name = c("Feuerman", "Solis", "Osborne", "Frizzell",
"Moran", "Seth"), Deadlift = c(320, 250, 340, 250, 250, 200),
Medicine_Ball = c(11.6, 8.8, 12.5, 9.2, 9.7, 9.1), HRP = c(46,
39, 36, 33, 42, 31), SDC = new("Period", .Data = c(37, 52,
47, 58, 59, 15), year = c(0, 0, 0, 0, 0, 0), month = c(0,
0, 0, 0, 0, 0), day = c(0, 0, 0, 0, 0, 0), hour = c(0, 0,
0, 0, 0, 0), minute = c(1, 1, 1, 1, 1, 2)), Leg_Tuck = c(20,
13, 4, 10, 13, 13), Run = new("Period", .Data = c(48, 59,
10, 53, 0, 29), year = c(0, 0, 0, 0, 0, 0), month = c(0,
0, 0, 0, 0, 0), day = c(0, 0, 0, 0, 0, 0), hour = c(0, 0,
0, 0, 0, 0), minute = c(13, 12, 17, 16, 0, 16)), Total = c(570,
508, 513, 470, 410, 452), Pass_Fail = structure(c(1L, 1L,
2L, 1L, 2L, 1L), .Label = c("Pass", "Fail"), class = "factor"),
Date = structure(c(18522, 18522, 18522, 18522, 18522, 18522
), class = "Date")), row.names = c(NA, -6L), class = c("tbl_df",
"tbl", "data.frame"))
As you can see, SDC is in minutes:seconds format. I achieved this using ms(data$SDC) to change the column type. I am trying to create a plot using geom_col that orders SDC from lowest to highest times. I am facing two problems:
When using the reorder command, the times are not properly reordered (see plot below).
The axes are being formatted by hour:minute:second but I want it to be formatted in only minute:second format (also see plot below).
Here is my code to generate the plot:
ggplot(data=data,
aes(x=reorder(Name, -SDC), y=SDC, fill=Pass_Fail)) +
scale_y_time(limits=c(0,200)) +
scale_fill_manual(values=c('#00BFC4', '#F8766D')) +
labs(x='Soldier', y='Sprint Drag Carry Time', fill='Passed/Failed ACFT', title='Sprint Drag Carry Scores') +
geom_col() +
geom_text(size=3, aes(label = SDC), hjust=-0.04) +
coord_flip() +
theme_classic()
It produces the following plot:
As you can see, the reordering is incorrect and the axes are not formatted the way I want them to be. Thanks in advance for your help.
I think reorder have trouble working with Period object. We can arrange the factor levels according to the value of SDC to get bars in increasing orders.
We can pass custom function for y-axis to get only minutes and seconds in labels.
library(tidyverse)
data %>%
arrange(SDC) %>%
mutate(Name = factor(Name, levels = unique(Name))) %>%
ggplot() + aes(x=Name, y=SDC, fill=Pass_Fail) +
scale_y_time(limits=c(0,200),
labels = function(x) sprintf('%02s:%02s', minute(x),second(x))) +
scale_fill_manual(values=c('#00BFC4', '#F8766D')) +
labs(x='Soldier', y='Sprint Drag Carry Time',
fill='Passed/Failed ACFT', title='Sprint Drag Carry Scores') +
geom_col() +
geom_text(size=3, aes(label = SDC), hjust=-0.04) +
coord_flip() +
theme_classic()

Overlapping two graphs with different y-axis in ggplot

I want to overlap two plots with different y-axis scales. I use stat_count() and geom_line. However, geom_line doesn't appear on the plot.
I use the following code.
library(ggplot2)
ggplot(X1, aes(x = Week)) +
stat_count() +
scale_x_continuous(breaks = seq(from = 0, to = 21, by = 1))+
scale_y_continuous(
name = expression("Count"),
limits = c(0, 20),
sec.axis = sec_axis(~ . * 15000 / 20, name = "Views"))+
geom_line(aes(y = Views), inherit.aes = T)
Here is the reproducible example of my data frame X1.
structure(list(Views = c(1749, 241, 309, 326, 237, 276, 2281,
1573, 10790, 1089, 1732, 3263, 2601, 2638, 2929, 3767, 2947,
65, 161), Week = c(1, 2, 2, 2, 3, 3, 4, 5, 5, 5, 6, 8, 8, 8,
8, 9, 10, 10, 10)), row.names = c(NA, -19L), class = c("tbl_df",
"tbl", "data.frame"))
Could you help me to put geom_line on the plot, please?
You also have to adjust the y values so that they fit inside the limits of the primary y-axis, i.e. apply the transfomation used for the secondary y-axis also inside geom_line. Try this:
X1 <- structure(list(Views = c(1749, 241, 309, 326, 237, 276, 2281,
1573, 10790, 1089, 1732, 3263, 2601, 2638, 2929, 3767, 2947,
65, 161), Week = c(1, 2, 2, 2, 3, 3, 4, 5, 5, 5, 6, 8, 8, 8,
8, 9, 10, 10, 10)), row.names = c(NA, -19L), class = c("tbl_df",
"tbl", "data.frame"))
library(ggplot2)
ggplot(X1, aes(x = Week)) +
stat_count() +
scale_x_continuous(breaks = seq(from = 0, to = 21, by = 1))+
scale_y_continuous(
name = expression("Count"),
limits = c(0, 20),
sec.axis = sec_axis(~ . * 15000 / 20, name = "Views"))+
geom_line(aes(y = Views / 15000 * 20), inherit.aes = T)
Created on 2020-05-21 by the reprex package (v0.3.0)
I also summarised the dataframe to improve the interpretation of the week 5 spike and plotted separate layers
x1 <- structure(list(Views = c(1749, 241, 309, 326, 237, 276, 2281,
1573, 10790, 1089, 1732, 3263, 2601, 2638, 2929, 3767, 2947,
65, 161), Week = c(1, 2, 2, 2, 3, 3, 4, 5, 5, 5, 6, 8, 8, 8,
8, 9, 10, 10, 10)), row.names = c(NA, -19L), class = c("tbl_df",
"tbl", "data.frame"))
x2 <- x1 %>%
group_by(Week) %>%
summarise(Views = sum(Views))
library(ggplot2)
ggplot() +
geom_line(data = x2, mapping = aes(x = Week, y = Views/15000 * 20))+
geom_bar(data = x1, mapping = aes(x = Week), stat = 'count')+
scale_x_continuous(breaks = seq(from = 0, to = 21, by = 1))+
scale_y_continuous( name = expression("Count"),
ylim.prim <- c(0, 20),
ylim.sec <- c(0, 15000),
sec.axis = sec_axis(~ . * 15000 / 20, name = "Views"))

Minor issue with plot in base R - unwanted lines showing at top of plot

I have created a plot in base R, including 3 clipped 'ablines'. Despite using the "frame.plot = FALSE" function, which removes the box around the plot (see image example1), when I add my clipped ablines [using ablineclip] new framing lines appear above them (see image example2).
The code I am using is shown below:
library(plotrix)
op <- par(mar=c(5, 6, 4, 2) + 0.1)
plot(dif2$land_area ~ dif2$Year_no, ylim = c(1,4000), col.axis = rgb(68, 84, 106,max=255),xaxt='n', type='o', pch=16, col='red', font.axis=2, font.lab=2, col.lab=rgb( 113, 113, 113, max=255), xlab = 'Year', ylab = 'Total Land Area Changed to \nResidential Development (Ha)', frame.plot = FALSE, cex=1.3)
rect(23.2,0,25.8,4000,col='grey',density = 8,border=T)
rect(10.2,0,11.8,4000,col='grey',density = 8,border=T)
xlim(0,30)
axis(1,at= 1:30,labels=F)
axis(1,at= 1:30,tick=F, font.axis=2, col.axis = rgb(68, 84, 106, max=255),labels= c(1989:2018))
# the below section is that which seems to create the issue #
ablineclip(lm(land_area ~ Year_no, data = subset(dif2, int==0)), col='blue', lty=2, x1=1,x2=10, lwd=0.8)
ablineclip(lm(land_area ~ Year_no, data = subset(dif2, int==0)), col='blue', lty=2, x1=12,x2=23, lwd=0.8)
ablineclip(lm(land_area ~ Year_no, data = subset(dif2, int==1)), col='blue', lty=2, x1=26,x2=30, lwd=0.8)
Does anyone have any ideas of why the ablineclip function appears to be altering the borders of the plot?
Cheers
You just need to set the y limits to the area clipped by ablineclip using the parameters y1 and y2, ensuring that y2 is below the top of your plot.
ablineclip(lm(land_area ~ Year_no, data = subset(dif2, int==0)),
col = 'blue', lty = 2, x1 = 1, x2 = 10, y1 = 1, y2 = 3500, lwd = 0.8)
ablineclip(lm(land_area ~ Year_no, data = subset(dif2, int==0)),
col = 'blue', lty = 2, x1 = 12, x2 = 23, y1 = 1, y2 = 3500, lwd = 0.8)
ablineclip(lm(land_area ~ Year_no, data = subset(dif2, int==1)),
col = 'blue', lty = 2, x1 = 26, x2 = 30, y1 = 1, y2 = 3500, lwd = 0.8)
Result:
Of course, I didn't have your data to work with so I had to make up a set that was similar (that's why the graph's shape is different to yours). The data I used was:
dif2 <- structure(list(Year_no = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28), land_area = c(3165, 3179, 3076, 2772, 2816, 2605, 2565,
2525, 2446, 2361, NA, 1966, 1911, 1790, 1819, 1710, 1673, 1555,
1434, 1220, 1174, 1021, 1564, NA, NA, 2479, 2539, 2872), int = c(0,
0, 0, 0, 0, 0, 0, 0, 0, 0, NA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, NA, NA, 1, 1, 1)), row.names = c(NA, -28L), class = "data.frame")
It's something in the code, see below, when you provide x1 and x2, it draws a line on the y limits + 1 :
> ablineclip
function (a = NULL, b = NULL, h = NULL, v = NULL, reg = NULL,
coef = NULL, untf = FALSE, x1 = NULL, x2 = NULL, y1 = NULL,
y2 = NULL, ...)
{
if (!is.null(c(x1, x2, y1, y2))) {
oldclip <- par("usr")
if (is.null(x1))
x1 <- oldclip[1]
if (is.null(x2))
x2 <- oldclip[2]
if (is.null(y1))
y1 <- oldclip[3]
if (is.null(y2))
y2 <- oldclip[4]
clip(x1, x2, y1, y2)
abline(h = oldclip[4] + 1)
You can hack the code and comment out this line, or just use abline with a combination of predict. First we simulate something like your data:
set.seed(123)
dif2 = data.frame(land_area= rnbinom(30,mu=1500,size=5),
Year_no = seq_along(1989:2018))
dif2$int = rep(0:1,c(23,7))
dif2$int[23:27] = 1
dif2[1989:2018 %in% c(1999,2012,2013),c("land_area","int")] = NA
And plot:
library(plotrix)
op <- par(mar=c(5, 6, 4, 2) + 0.1)
plot(dif2$Year_no, dif2$land_area,ylim = c(1,4000), col.axis = rgb(68, 84, 106,max=255),xaxt='n', type='o', pch=16, col='red', font.axis=2, font.lab=2, col.lab=rgb( 113, 113, 113, max=255), xlab = 'Year', ylab = 'Total Land Area Changed to \nResidential Development (Ha)', frame.plot = FALSE, cex=1.3)
rect(23.2,0,25.8,4000,col='grey',density = 8,border=T)
rect(10.2,0,11.8,4000,col='grey',density = 8,border=T)
axis(1,at= 1:30,labels=F)
axis(1,at= 1:30,tick=F, font.axis=2, col.axis = rgb(68, 84, 106, max=255),labels= c(1989:2018))
We make the two fits, and you use predict to get the y values
fit1=lm(land_area ~ Year_no, data = subset(dif2, int==0))
fit2=lm(land_area ~ Year_no, data = subset(dif2, int==1))
lines(1:10,predict(fit1,data.frame(Year_no=1:10)),lty=8,col="blue")
lines(12:23,predict(fit1,data.frame(Year_no=12:23)),lty=8,col="blue")
lines(26:30,predict(fit2,data.frame(Year_no=26:30)),lty=8,col="blue")

Changing x-axis tick labels ggplot2 not working, making axis disappear, scale_x_discrete

I'm trying to change the x-axis tick labels in ggplot but I can't get it to work for some reason. I have the following code and plot:
ggplot(over36mo, aes(x=raceeth,y=pt,fill=factor(year.2cat))) +
geom_bar(stat="identity",position="dodge") +
geom_errorbar(aes(ymax=pt+se, ymin=pt-se), width=0.2, position=position_dodge(0.9)) +
scale_fill_discrete(guide=FALSE) +
scale_y_continuous(breaks=seq(0, 0.26, 0.02), limits=c(0,0.26)) +
labels=c("NHW","NHB","NHNA/PI","NHA","H")) +
theme(axis.line.x=element_line(color="black"),
axis.line.y=element_line(color="black"),
panel.background=element_blank(),
panel.border=element_blank(),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
plot.background=element_blank()) +
xlab("All ages") + ylab("")
But when I try to change 1, 2, 3, 4, 5 to different labels with scale_x_discrete, the x-axis disappears like so:
ggplot(over36mo, aes(x=raceeth,y=pt,fill=factor(year.2cat))) +
geom_bar(stat="identity",position="dodge") +
geom_errorbar(aes(ymax=pt+se, ymin=pt-se), width=0.2, position=position_dodge(0.9)) +
scale_fill_discrete(guide=FALSE) +
scale_y_continuous(breaks=seq(0, 0.26, 0.02), limits=c(0,0.26)) +
labels=c("NHW","NHB","NHNA/PI","NHA","H")) +
theme(axis.line.x=element_line(color="black"),
axis.line.y=element_line(color="black"),
panel.background=element_blank(),
panel.border=element_blank(),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
plot.background=element_blank()) +
xlab("All ages") + ylab("") +
scale_x_discrete(breaks=c("1","2","3","4","5"), labels=c("NHW","NHB","NHNA/PI","NHA","H")) +
It's probably obvious what's wrong but I can't figure it out. Here's a dput of my data if someone wants to give it a shot!
dput(over36mo)
structure(list(z.surv.mos = c(36, 36, 36, 36, 36, 36, 36, 36,
36, 36), raceeth = c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5), year.2cat = c(1,
2, 1, 2, 1, 2, 1, 2, 1, 2), pt = c(0.10896243930756, 0.12919986395988,
0.10763696166101, 0.0918969557367, 0.14186152615109, 0.12701814940611,
0.05405405405405, 0.09393141727008, 0.08880901672474, 0.11716939090588
), nevent = c(9, 3, 0, 0, 2, 1, 0, 0, 1, 1), ncensor = c(0, 9,
0, 1, 0, 2, 0, 1, 0, 0), nrisk = c(311, 96, 33, 9, 72, 21, 2,
2, 48, 20), cum.ev = c(2474, 2469, 287, 342, 440, 496, 35, 40,
505, 616), cum.cen = c(1, 958, 4, 107, 12, 198, 0, 13, 19, 239
), pointflg = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), pe = c(0.89103756069243,
0.87080013604011, 0.89236303833898, 0.90810304426329, 0.8581384738489,
0.87298185059388, 0.94594594594594, 0.90606858272991, 0.91119098327525,
0.88283060909411), se = c(0.00591553159512, 0.00860912091676,
0.01746946721576, 0.01975702415208, 0.01550071018085, 0.01904081251339,
0.03717461110299, 0.05797150600236, 0.01228353765126, 0.01608823714602
), lower.cl = c(0.09796374785164, 0.11338170396883, 0.07830897003442,
0.06029765195198, 0.11451353670001, 0.09468155080317, 0.01404207131432,
0.02802051731609, 0.06772108402588, 0.08952365586359), upper.cl = c(0.12119598770184,
0.14722485430136, 0.14794876641234, 0.1400560419898, 0.17574073058836,
0.17039866945242, 0.20807761862723, 0.31488038035974, 0.11646360310182,
0.15335238527538)), .Names = c("z.surv.mos", "raceeth", "year.2cat",
"pt", "nevent", "ncensor", "nrisk", "cum.ev", "cum.cen", "pointflg",
"pe", "se", "lower.cl", "upper.cl"), row.names = c("38", "134",
"183", "246", "289", "366", "412", "452", "491", "563"), class = "data.frame")
It's because you are setting a discrete x scale but your x values are numeric. If you want to treat them as discrete, convert to a factor. Just change the first part to
ggplot(over36mo, aes(x=factor(raceeth), y=pt, fill=factor(year.2cat)))
and it should work just fine.

Resources