-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch to jsonlite #28
Conversation
Thanks @yihui. I think the rationale behind sticking with On the issue of conversion of data frames to JSON, while I agree that row/record based makes more sense, the columns based approach leads to smaller payloads. @jjallaire has authored a Once @jcheng5 is comfortable with moving |
Here is @wch's shiny PR switching to jsonlite: rstudio/shiny#606 I'm not sure whether or when we will get it done, but personally I'd vote for the switch. I see the point of payloads, which makes perfect sense. It is possible with jsonlite, and widget authors can opt-in by turning data frames to lists, then use dataframeToD3() if they do not like the default row-based representation. With RJSONIO, there is no way to opt-in if we do want the row-based JSON data. |
@yihui my vote is for the switch too. But I would want to do it in sync with @wch's shiny PR so that users can get things to work out of the box. One approach for now might be to maintain a @jjallaire @jcheng5 any thoughts on this? |
That sounds good to me. FWIW, I'm not saying this is an urgent issue. I just feel it might be a better option in the long term. |
The long encoding of dataframes is massively less efficient than wide though. > nchar(jsonlite::toJSON(cars)) # long
[1] 1144
> nchar(jsonlite::toJSON(as.list(cars))) # wide
[1] 313 It's a single JS function call to transform from wide to long, I think it's far preferable to transport the data efficiently and then transform it on the client side. I think even if/when we move to jsonlite in Shiny, I'd want to discuss more about whether we should change to long-encoding of dataframes, especially when it breaks compatibility with existing output bindings. (Update: Sorry, had pasted in the example) |
That said, RJSONIO does wide but sticks in tons of meaningless whitespace padding even with |
UGH > nchar(RJSONIO::toJSON(cars, pretty=TRUE))
[1] 626
> nchar(RJSONIO::toJSON(cars, pretty=FALSE))
[1] 829 |
The row based json is pretty much the standard though. Even when performance should be a concern (e.g. mongodb, crossfilter or web-apis), most applications seems to use row-based encoding because it is much more flexible, especially when data include missing or nested nested fields. So if you want smooth interoperability, I think the row-based format is preferable. Whether that weighs up to some network overhead depends on the average size of your data I guess. If you are worried about bandwidth, also take into account that most http uses gzip, which makes the overhead significantly smaller:
|
gzip doesn't work on websocket connections (yet), I only wish... |
Ah I didn't know that, good to know. But it seems like the proposals for ws compression are ready and being implemented, so that will likely solve itself, soon-ish :) |
I just added an experimental commit (a7fdb4d) that allows package authors to customize the list(order = list(
list(jsonlite::unbox(1), jsonlite::unbox('asc')),
list(jsonlite::unbox(2), jsonlite::unbox('desc'))
)) to get Or we can even make the JSON conversion function customizable via, say, an attribute |
This is a nice idea @yihui. Let me think through the potential consequences of providing this flexibility. |
The |
@ramnathv That is nice, but I'm wondering how can one actually make use of it if we do not have control over the JSON encoding function. |
@yihui I was merely clarifying the origin of the |
@ramnathv Got you 👍 |
…SON and shiny:::toJSON are in sync
@hafen Please see the one-liner fix at bokeh/rbokeh#56 @smartinsightsfromdata I'll take a look at rhandsontable soon. |
For |
This branch seems is working fine with threejs so no problem from me if you merge this. The threejs widget uses the rjson package on its own in a few places. I will work on moving that over to jsonlite this weekend, and expect to push threejs to cran maybe Sunday night. |
@yihui I think @jrowen's problem is what I was afraid of with verbatim json includes. When the user legitimately wants to include a json string to parse it manually on the client, you will get unexpected results when the json gets included verbatim. @jrowen Try using |
OK, I spoke too soon. Something else is wrong with this PR, perhaps unrelated to the use of jsonlite. My threejs shiny examples are broken, with undefined arguments in the JavaScript render function. Those examples work fine with the released version of htmlwidgets. I'll try to track down exactly what is causing this problem, but please hold off merging this. |
@jeroenooms The I'm running now into an "Input to asJSON(keep_vec_names=TRUE)..." message when passing a |
@jeroenooms @jrowen Wait a minute. I guess we are heading to the wrong direction by using |
@bwlewis might your issues be caused by |
@ThomasSiegmund , you might be interested in this discussion. Could you try your D3TableFilter with this pull?
|
@bwlewis I sent a PR to you and tested your shiny examples under https://github.com/bwlewis/rthreejs/tree/master/inst/examples and other static examples in the documentation. I did not see any issues. Please let me know you still have any problems (a reproducible example will be helpful). @jrowen I verified what I was thinking: your use of |
@timelyportfolio @yihui |
@bwlewis Great!! I think @timelyportfolio was correct that @timelyportfolio I tested @ThomasSiegmund's D3TableFilter package, and the examples still work fine. |
Hi all, I can confirm that D3TableFilter works fine. I get a warning about a named Thanks for taking care Thomas On Sun, Apr 12, 2015 at 1:29 AM, Yihui Xie [email protected] wrote:
|
I've re-tested my widgets:
And they all work fine, beside the warning below in rdatamaps (already corrected by @yihui in rhandsontable, so I have an idea where to look to fix this): Input to asJSON(keep_vec_names=TRUE) is a named vector. In a future version of jsonlite, this option will not be supported, and named vectors will be translated into arrays instead of objects. If you want JSON object output, please use a named list instead. See ?toJSON Many thanks to everyone: it is really rewarding been part of this community. |
@ThomasSiegmund @smartinsightsfromdata You just need to find out where the named vector is created, and turn it into a named list instead. Here is the fix I provided to rhandsontable: https://github.com/yihui/rhandsontable/commit/67462eb9156edc480572f2f89eeed7d8587595f6 |
FYI the new jsonlite is on CRAN already. |
@@ -13,7 +13,7 @@ License: MIT + file LICENSE | |||
VignetteBuilder: knitr | |||
Imports: | |||
htmltools (>= 0.2.6), | |||
RJSONIO, | |||
jsonlite, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a version requirement for jsonlite or will any version work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should specify that it is the latest version. (>= 0.9.16.9000)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going by the CRAN version, this should be jsonlite (>= 0.9.16)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Done.
This might be a breaking change to the existing widget packages, but I think it should be easy for them to adapt to this change. My personal experience is that, among several other advantages, jsonlite covers the corner cases much better than RJSONIO. The default treatment of data frames also makes better sense to JS libraries (record/row-based instead of column-based). Another bonus point is @jeroenooms is extremely responsive, so we can bug him before he becomes a busy super star :-p
TODO: