If the column names of a data.frame
are started with numbers, or have spaces, aes_string()
fails to handle them:
foo=data.frame(\"1
I had similar situation and I used `` to make it understand:
mydf$ROIs <- row.names(mydf)
df.long <- melt(mydf)
colnames(df.long)[3] <- "Methods"
colnames(df.long)[4] <- "Mean L2 Norm Error"
variable.name="Variable", na.rm=TRUE)
ggplot(df.long, aes(ROIs, `Mean L2 Norm Error`, fill=Methods))+
geom_bar(stat="identity",position="dodge")+
theme(axis.text.x=element_text(angle=45,hjust=1,vjust=1))
As far as I can tell, this method should work programmatically:
foo=data.frame("1st Col"=1:5, "2nd Col"=5:1, check.names=F)
#Save the colnames
bar=colnames(foo)
#change the names to something usable
names(foo) <- c("col1", "col2")
#Plot with arbitrary labs
ggplot(foo, aes(x=col1, y=col2)) + geom_point()+
labs(x=bar[1], y=bar[2])
You can use the function aes_string2
below instead of aes_string
:
aes_string2 <- function(...){
args <- lapply(list(...), function(x) sprintf("`%s`", x))
do.call(aes_string, args)
}
The original question asked how to modify a value of a variable so it is acceptable to ggplot() when the value is not know beforehand.
Write a function that adds back-ticks to the beginning and end of the value of the variable:
# ggName -> changes a string so it is enclosed in back-ticks.
# This can be used to make column names that have spaces (blanks)
# or non-letter characters acceptable to ggplot2.
# This version of the function is vectorized with sapply.
ggname <- function(x) {
if (class(x) != "character") {
return(x)
}
y <- sapply(x, function(s) {
if (!grepl("^`", s)) {
s <- paste("`", s, sep="", collapse="")
}
if (!grepl("`$", s)) {
s <- paste(s, "`", sep="", collapse="")
}
}
)
y
}
Examples:
ggname(12)
[1] 12
ggname("awk ward")
"`awk ward`"
l <- c("awk ward", "no way!")
ggname(l)
"`awk ward`" "`no way!`"