Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R ggvis multiple plots from single data frame

Tags:

r

dplyr

ggvis

I've searched, so please forgive me if I'm missing something.

Let's assume a dataframe that contains Name, Date, Calories, where Calories is the total number of calories that person consumed that day.

Name    Date    Calories
Amy     1/1/01  1500
Amy     1/2/01  1600
Amy     ...     ...
Sue     1/1/01  1450
Sue     1/1/02  1500
Sue     ...     ...
Jim     ...     ...

What I'd like to do is to use ggvis to plot calories for each person (Name). I know I can use dplyr's group_by, and get this on a single plot, but that will be too busy. And I know I could use dplyr's filter and filter out each person and make a graph for each person, but that doesn't scale.

Is there a way to have ggvis spit out a plot of calories per day for each person automatically?

Note that I tried creating a function like the below:

makeCharts <- function(myName){
   myTbl %>% filter(Name == myName) %>% ggvis(~Date, ~Calories)
}

It works great when you call it manually:

makeCharts("Amy")

But when you call it via sapply:

sapply(levels(myTbl$Name), makeCharts)

The output looks like this:

           Amy    Sue    Jim    John   Sally  Frank  Sandy   etc...     
marks      List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0  List,0 List,0 List,0 List,0  List,0 List,0
data       List,1 List,1 List,1 List,1 List,1 List,1 List,1 List,1 List,1  List,1 List,1 List,1 List,1  List,1 List,1
props      List,1 List,1 List,1 List,1 List,1 List,1 List,1 List,1 List,1  List,1 List,1 List,1 List,1  List,1 List,1
reactives  List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0  List,0 List,0 List,0 List,0  List,0 List,0
scales     List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0  List,0 List,0 List,0 List,0  List,0 List,0
axes       List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0  List,0 List,0 List,0 List,0  List,0 List,0
legends    List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0  List,0 List,0 List,0 List,0  List,0 List,0
controls   List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0  List,0 List,0 List,0 List,0  List,0 List,0
connectors List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0  List,0 List,0 List,0 List,0  List,0 List,0
handlers   List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0  List,0 List,0 List,0 List,0  List,0 List,0
options    List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0 List,0  List,0 List,0 List,0 List,0  List,0 List,0
cur_data   ?      ?      ?      ?      ?      ?      ?      ?      ?       ?      ?      ?      ?       ?      ?     
cur_props  List,2 List,2 List,2 List,2 List,2 List,2 List,2 List,2 List,2  List,2 List,2 List,2 List,2  List,2 List,2
cur_vis    NULL   NULL   NULL   NULL   NULL   NULL   NULL   NULL   NULL    NULL   NULL   NULL   NULL    NULL   NULL  
like image 572
John Tarr Avatar asked Aug 17 '15 20:08

John Tarr


1 Answers

One option is to use do. The do function from dplyr can be used for functions that return objects like this, and allows you to easily make a separate plot for each level of some grouping variable.

For your basic example, you just need to edit your function with the desired plot but with the dataset as the only argument.

makeCharts = function(dat) {
    dat %>% ggvis(~Date, ~Calories)
}

Then group your dataset and make a plot per group via do. The . refers to the dataset for each group. I named the output column that contains the list of plots plots.

allplots = myTbl %>%
    group_by(Name) %>%
    do(plots = makeCharts(.))

The resulting object looks like this:

Source: local data frame [2 x 2]
Groups: <by row>

  Name      plots
1  Amy <S3:ggvis>
2  Sue <S3:ggvis>

To print all the plots to the plotting window in a row, you just need to run allplots$plots. You can extract just a single plot via, e.g., allplots$plots[[1]].

Edit

You can use anything from the dataset within do by referring to the dataset via .. For example, if you wanted to add a title with the group name like this answer shows how to do, you could make a new function to include this with a second argument:

makeCharts2 = function(dat, group) {
    dat %>% ggvis(~Date, ~Calories) %>%
            add_axis("x", title = "Date") %>%
            add_axis("x", orient = "top", ticks = 0, title = paste("Plot for", group),
                         properties = axis_props(
                                axis = list(stroke = "white"),
                                labels = list(fontSize = 0)))
}

Then just add the group name as the second argument to the function. One way to do this is via unique.

allplots2 = myTbl %>%
    group_by(Name) %>%
    do(plots = makeCharts2(., unique(.$Name)))
like image 67
aosmith Avatar answered Sep 23 '22 04:09

aosmith