1

I am trying to automate the setting of the linetype in a ggplot call which I will run inside a for loop. The data have around 20 values in the var2 variable, which I loop through taking Eurostoxx (the index) and one other value to graph at a time.

here is the first row:

       Date value             var1                  var2

       2011-09-30 20.67 Return on Equity             Eurostoxx

I would like to have the Eurostoxx as a solid line in each graph (it is confusing to readers when it switches).

I know how to set the linetype manually:

gp<- gp +  scale_linetype_manual("",values=c("Eurostoxx"="dotted","Automobiles and Parts"="solid"))

but my attempt to automate this

secnam<-unique(g$var2)[!unique(g$var2)%in%"Eurostoxx"]
secnam

#"Automobiles and Parts"

gp<- gp +  scale_linetype_manual("",values=c("Eurostoxx"="dotted",secnam="solid"))

runs into the error

Error in data.frame(scale$output_breaks(), I(scale$labels())) : row names contain missing values

The below code reproduces the problem.

gfull<-structure(list(Date = structure(c(15247, 15278, 15308, 15338,
15247, 15278, 15308, 15338, 15247, 15278, 15308, 15338, 15247,
15278, 15308, 15338, 15247, 15278, 15308, 15338, 15247, 15278,
15308, 15338), class = "Date"), value = c(20.67, 19.81, 19.81,
19.92, 1.2966, 1.4054, 1.3744, 1.3828, 16.36, 16.58, 16.86, 16.7,
0.8263, 0.9167, 0.8642, 0.8197, 13.32, 12.82, 12.59, 12.55, 1.1672,
1.1721, 1.1643, 1.1509), var1 = c("Return on Equity", "Return on Equity",
"Return on Equity", "Return on Equity", "Price to Book", "Price to Book",
"Price to Book", "Price to Book", "Return on Equity", "Return on Equity",
"Return on Equity", "Return on Equity", "Price to Book", "Price to Book",
"Price to Book", "Price to Book", "Return on Equity", "Return on Equity",
"Return on Equity", "Return on Equity", "Price to Book", "Price to Book",
"Price to Book", "Price to Book"), var2 = c("Eurostoxx", "Eurostoxx",
"Eurostoxx", "Eurostoxx", "Eurostoxx", "Eurostoxx", "Eurostoxx",
"Eurostoxx", "Automobiles and Parts", "Automobiles and Parts",
"Automobiles and Parts", "Automobiles and Parts", "Automobiles and Parts",
"Automobiles and Parts", "Automobiles and Parts", "Automobiles and Parts",
"Utilities", "Utilities", "Utilities", "Utilities", "Utilities",
"Utilities", "Utilities", "Utilities")), .Names = c("Date", "value",
"var1", "var2"), row.names = c(71L, 72L, 73L, 74L, 4511L, 4512L,
4513L, 4514L, 145L, 146L, 147L, 148L, 4585L, 4586L, 4587L, 4588L,
1477L, 1478L, 1479L, 1480L, 5917L, 5918L, 5919L, 5920L), class = "data.frame")

The code:

g<-gfull
g<-subset(gfull, var2 %in% c("Eurostoxx","Automobiles and Parts") )

  gp <- ggplot(g, aes(Date, value,group=var2,lty=var2))
  gp <-gp + facet_grid(var1~., scales="free")
  gp<- gp + geom_line()

#EUROSTOXX is dotted

g<-gfull
g<-subset(g,var2%in%c("Eurostoxx","Utilities"))
  gp <- ggplot(g, aes(Date, value,group=var2,lty=var2))
  gp <-gp + facet_grid(var1~., scales="free")
  gp<- gp + geom_line()

#EUROSTOXX is solid

  secnam<-unique(g$var2)[!unique(g$var2)%in%"Eurostoxx"]
   gp<- gp +  scale_linetype_manual("",values=c("Eurostoxx"="dotted",secnam="solid"))
   gp

  #Error in data.frame(scale$output_breaks(), I(scale$labels())) :
  #row names contain missing values
3
  • Can you format your code using the code chunks? Commented Jan 16, 2012 at 18:07
  • you could create a new variable in your data.frame containing the linetype values that you want, and use scale_linetype_identity (untested). Commented Jan 16, 2012 at 20:03
  • Thanks for the comments guys. I will look up this code chunks feature for next time. Baptiste, your suggestion was right, as Joran has fleshed out below. Commented Jan 17, 2012 at 8:47

1 Answer 1

1

There are probably more elegant ways of doing what you're trying to accomplish, but to address your specific issue, let's examine what exactly c("Eurostoxx"="dotted",secnam="solid") is:

> c("Eurostoxx"="dotted",secnam="solid")
Eurostoxx    secnam 
 "dotted"   "solid"

Note that you tried to name the element "solid" with the value in secnam, but R doesn't work that way. (At least, not without delving into using eval, parse, substitute and the like, but that's more complicated than we need.)

Instead, just create the vector of linetypes and then modify the names directly, using the names function:

> l <- c("dotted","solid")
> names(l) <- c("Eurostoxx",unique(g$var2)[!unique(g$var2)%in%"Eurostoxx"])
> l
Eurostoxx Utilities 
 "dotted"   "solid"

and then pass the vector l to scale_linetype_manual in the values argument.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Joran for this solution, and for taking the time to explain my mistake. This works perfectly and seems pretty elegant to me. I guess elegance is in the eye of the beholder. Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.