2
votes

I have the following simple data.table:

          date     user              time
 1: 2016-04-25 3533f254   2.21666667 secs
 2: 2016-05-02 e627fa24   1.45833333 secs
 3: 2016-05-02 451872fe   5.08333333 secs
 4: 2016-05-02 105826aa  42.75000000 secs
 5: 2016-05-02 9a527a36 122.78333333 secs
 6: 2016-05-09 451872fe  89.82500000 secs
 7: 2016-05-09 9a527a36   3.06000000 secs
 8: 2016-05-09 cbbc1b3a   0.03014352 secs
 9: 2016-05-16 451872fe   0.55000000 secs
10: 2016-05-16 9a527a36   0.45000000 secs

How can I create a stacked bar chart of this type of data.table using plotly (perhaps using data.table- or plotly-specific functionality)? The actual data has many more rows of dates, users and times. The x-axis should correspond to the date, the y-axis to the time taken, and the bars should be stacks of users.

The typical way to do this sort of barchart in plotly seems to be something like

p1 <- plot_ly(x = x1, y = y1, type = "bar")
p2 <- add_trace(p1, x = x2, y = y2)
p3 <- add_trace(p2, x = x3, y = y3)
p4 <- layout(p3, barmode = "stack")
p4

but in this case specifying each x,y group manually is infeasible due to the number of rows of data.

Sample input:

dt <- as.data.table(structure(list(date = structure(c(1L, 2L, 2L, 2L, 2L, 3L, 3L, 
3L, 4L, 4L), .Label = c("2016-04-25", "2016-05-02", "2016-05-09", 
"2016-05-16", "2016-05-23", "2016-05-30", "2016-06-06", "2016-06-13", 
"2016-06-20", "2016-06-27", "2016-07-04", "2016-07-11", "2016-07-18", 
"2016-07-25", "2016-08-01", "2016-08-08", "2016-08-15", "2016-08-22", 
"2016-08-29"), class = "factor"), user = list("3533f254", "e627fa24", 
    "451872fe", "105826aa", "9a527a36", "451872fe", "9a527a36", 
    "cbbc1b3a", "451872fe", "9a527a36"), time = structure(c(2.21666666666667, 
1.45833333333333, 5.08333333333333, 42.75, 122.783333333333, 
89.825, 3.06, 0.0301435185185185, 0.55, 0.45), units = "secs", class = "difftime")), .Names = c("date", 
"user", "time"), class = "data.frame", row.names = c(NA, -10L
)))
2

2 Answers

3
votes

First, your user column is a list for some reason, so let's fix that:

dt[, user := unlist(user)]

Now, I've never worked with plotly, so I don't know what the result should be, but this will replicate what you described you want to do:

dt[, {if (.GRP == 1)
        plot_ly(x = date, y = time, type = 'bar')
      else
        add_trace(x = date, y = time)
     }, by = user]

layout(barmode = "stack")
0
votes

Unfortunately the other answers didn't work. The easiest solution was to create the stacked bar chart using ggplot2 and then convert it using plotly:

(ggplot(data = dt, aes(date, time, fill=user)) + geom_bar(stat="identity")) %>% ggplotly()