ggvis: Interaction Plot

☆樱花仙子☆ 提交于 2019-12-06 05:52:06

The basic problem, when trying to implement this in ggvis, is that there is no position = dodge option like in ggplot2, and therefore the boxplots for different supp values cannot be plotted at the same x coordinate. So indexing the x axis by as.factor(dose) doesn't appear to be an option. However, what we can do is use an integer index of length equal to the number of unique dose values, and then manually offset the x position of the data to the left or right, according to the supp value:

library(ggvis)
library(dplyr)
d <- ToothGrowth
d$xpos <- as.integer(factor(d$dose)) + ifelse(d$supp == "OJ", -.2, .2)

So we can now use x = ~xpos to plot the boxplots at the right positions. The next step is to define the data holding the means used to plot the points that are connected by lines.

means <- d %>% group_by(dose, supp) %>% summarise(len = mean(len))
means$xpos <- as.integer(factor(means$dose))
means <- group_by(means, supp) # The grouping is needed for layer_paths()

The graph can now be obtained as

ggvis(d, x = ~xpos, y = ~len, stroke = ~supp) %>% 
    layer_boxplots() %>%
    layer_points(data = means, fill := "blue") %>%
    layer_paths(data = means)

Now we have the problem that the x position of the plots will be at 1, 2, 3 rather than the actual dose values. This is not very straightforward to overcome because add_axis() gives no way to re-label the axis ticks (also, we couldn't have used the actual dose values instead of 1, 2, 3 in the first place because that would have placed the boxplots at dose values 0.5 and 1 closer to each other than the ones at dose values 1 and 2). This can be overcome by a not so elegant hack, which is to add an axis for each single dose value. The function add_axis() gives a way to modify the axis properties (which includes the labels) but it will use the same label for the whole axis, since the properties apply to the whole axis. So by adding an axis for each dose value, we can manipulate the labels one by one. This looks like

ggvis(d, x = ~xpos, y = ~len, stroke = ~supp) %>% 
    layer_boxplots() %>%
    layer_points(data = means, fill := "blue") %>%
    layer_paths(data = means) %>%
    add_axis("x", title = "Dose", 
        values = c(1, 1), # For some reason values of length 1 don't work...
        properties = axis_props(labels = list(text = "0.5"))) %>%
    add_axis("x", title = "", 
        values = c(2, 2), 
        properties = axis_props(labels = list(text = "1"))) %>%
    add_axis("x", title = "", 
        values = c(3, 3), 
        properties = axis_props(labels = list(text = "2"))) %>%     
    add_axis("y", title = "Response")

Alternatively, you can use a loop for these so you don't have to type the same thing over and over

labs <- data.frame(dose = unique(d$dose))
labs$xpos <- as.integer(factor(labs$dose))

v <- ggvis(d, x = ~xpos, y = ~len, stroke = ~supp) %>% 
    layer_boxplots() %>%
    layer_points(data = means, fill := "blue") %>%
    layer_paths(data = means) %>%
    add_axis("x", title = "Dose", ticks = 0) %>%
    add_axis("y", title = "Response")

for (i in 1:nrow(labs)) {
    v <- add_axis(v, "x", title = "", values = rep(labs[i, "xpos"], 2),
        properties = axis_props(labels = list(text = as.character(labs[i, "dose"]))))
}

The final outcome looks like this

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!