I'm trying to figure out what I'm doing wrong passing arguments to ggplot. I've come a long way with existing posts, but have hit a wall here. Probably something stupid, but here goes (I'm leaving out some of the plot formatting since that is not where the problem is):
melted data set "lagres" is the same in both scenarios.
> str(lagres)
'data.frame': 30 obs. of 4 variables:
$ ST : Factor w/ 3 levels
$ year : Factor w/ 6 levels
$ variable: Factor w/ 2 levels
$ value : num
The first plotting call works great:
ggplot(lagres, aes(quarter, value, group = interaction(ERTp, variable), linetype = variable, color = ERTp, shape = variable ))
Trying to convert this to accept arguments and be re-used in a for-loop script does NOT work, even though the structure is really the same:
timevar <- "quarter"
grpvar <- "ERTp"
fplot <- function(lagres, timevar, grpvar, ylb, tlb){
plot <- ggplot(lagres, aes_string(x=timevar, y="value", group = interaction("variable", grpvar), linetype = "variable", color = grpvar, shape = "variable")) +
geom_line(size = 0.5) + geom_point(size = 3) +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) + labs(y = ylb) +
ggtitle(paste(tlb, grpvar, today, sep = ", ")) +
theme(plot.title = element_text(lineheight = .8, face = "bold", hjust = 0.5))
fplot(lagres, timevar, grpvar)
Error: geom_path: If you are using dotted or dashed lines, colour, size and linetype must be constant over the line
The problem seems to lie with the "linetype" arg, as removing this results in an appropriate graph in terms of values/colors, but the lines connected wrong and obviously no separate line for each variable/grp.
Trying to analyze the problem further by looking at the structure of the argument, it looks like aes() and aes_string() parse the group interaction differently. Maybe this is the problem. Parsing the "aes()" formulation with raw variables, I get:
> str(aes(quarter, value, group = interaction(ERTp, variable), linetype = variable, color = ERTp, shape = variable ))
List of 6
$ x : symbol quarter
$ y : symbol value
$ group : language interaction(ERTp, variable)
$ linetype: symbol variable
$ colour : symbol ERTp
$ shape : symbol variable
Then, the "aes_string()" method with referenced arguments:
> str(aes_string(timevar, "value", group = interaction(grpvar, "variable"), linetype = "variable", color = grpvar, shape = "variable" ))
List of 6
$ group : Factor w/ 1 level "ST.variable": 1
$ linetype: symbol variable
$ colour : symbol ST
$ shape : symbol variable
$ x : symbol quarter
$ y : symbol value
So, having the group be either a "language interaction" vs. a 1-level factor, would make a difference? Can't figure out what to do about that parsing issue so the group interaction comes out properly. Saw somewhere that "paste()" could be used, but, no, that does not work. Passing ALL arguments (thus, no quoted text in the aes_string() formula) does not help either.
> dput(lagres)
structure(list(ST = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L,
3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 3L, 1L, 2L,
3L, 2L, 3L, 1L, 3L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("GeraghtyM",
"Other", "WeenJ"), class = "factor"), quarter = structure(c(1L,
1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L,
6L, 7L, 7L, 7L, 1L, 2L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 6L, 6L,
6L, 7L, 7L, 7L), .Label = c("2015-Q2", "2015-Q3", "2015-Q4",
"2016-Q1", "2016-Q2", "2016-Q3", "2016-Q4"), class = "factor"),
variable = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("ScanLag",
"TPADoorToLag"), class = "factor"), value = c(45.3333333333333,
60.2857142857143, 37.6, 0, 51.375, 95.4166666666667, 26.8,
42.75, 200, 28, 134, 68.2941176470588, 29, 42.8, 140.7, 0,
49.2222222222222, 103.833333333333, 0, 20.125, 0, 67.75,
48, 87, 93, 78, 49.5, 55, 65.6, 83, 59, 54, 153, 114, 111,
83, 8.66666666666667)), .Names = c("ST", "quarter", "variable",
"value"), row.names = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L,
11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 24L, 25L,
26L, 27L, 29L, 30L, 31L, 33L, 35L, 36L, 37L, 38L, 39L, 40L, 41L,
42L), class = "data.frame", na.action = structure(c(22L, 23L,
28L, 32L, 34L), .Names = c("22", "23", "28", "32", "34"), class = "omit"))
geom_path
part of the code) and a small example of your dataset. See here for some examples of how to add data to a question. – aosmith