This is not yet a practical question but rather a theoretical one. I was thinking of using Shiny to display some raw data in an interactive way. This is fine.
However - is it possible to have users change the data that is displayed?
Say, if I have a bunch of sliders for users to restrict the underlying data to satisfy certain conditions and have these observations displayed - is it possible to allow the users to make modifications to that data and have these modifications sent back to the server, which in turn saves these changes?
I am thinking of scenarios where users may use a Shiny Application to browse through data and detect potential outliers in the data -- the user can then flag these as outliers. However, that information needs to be passed back to the server.
Is such an application possible? Are there some existing examples?
You can basically do almost anything in Shiny since you can create your own input and output bindings – so the answer to your question is yes, what you're asking is possible. Say you have a data frame that you send to a web page to be viewed by the user. As an example, you want to allow users to simply click a cell if it's an outlier that should be removed (replaced with
NA
).Let's say the data frame looks like this:
From shiny you would construct a normal HTML table that might look something like this when displayed on the webpage:
Now break out the jQuery and bind a click event so that when a cell is clicked you can record the row and column number (see here) and then replace that cell with
NA
in Shiny. Your input binding might look something like (see here for details of what's going on here):There's a lot going on here, but generally these input bindings are fairly similar to each other. The most important thing is the
setValue()
function. What should be happening there (this is untested) is the row and column number of the cell being clicked is recorded and posted back to the server.Then from Shiny you would simply do something like:
You will probably need to make an output binding for output$outliers as well. This is simplified code here obviously, you would need to apply error checking etc.
This is just an example. In reality, you would probably not have Shiny updating your data frame every single time a user makes a change. You would want to have some sort of submit button so that once the user has made all of his/her changes they can be applied.
I haven't even remotely tested any of this so there are almost certainly some errors. But since you were just asking a theoretical question I didn't check it too much. The general tactic should work anyway. With input bindings you can get anything from a web page back to the server and vice versa with output bindings. Maybe saying "anything" is a stretch — but you can do a lot.
I have been working on a package that uses this workflow:
This is not the usual way Shiny is used - the app isn't being deployed remotely, but instead is used locally to serve as an interactive plotting interface for a single user. I have done similar things with base graphics and the
locator()
function, which is tedious. It may be easier to use tcl/tk, but I was curious to see how it might work with Shiny.Here's a toy example:
In this case, clicking on a point increases the value of one of the columns ("size") in the corresponding row (which is visualized using the
cex
argument when plotted). The values are returned to the user and, in this case, stored in themodDF
variable:It would be easy to modify this to toggle the value in an 'outlier' column (so that you could reverse your decision), or to directly make permanent changes in the data frame.
In my actual package, I use this approach to allow the user to visually select initial parameters for a non-linear regression, immediately see the resulting model fit plotted in the browser, repeat until they get a fitted model that looks sensible, and finally save the results and return to their R session.