Fix rendering vctrs::list_of columns #1181
Open
+20
−1
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
DT needs to convert data frames/tibbles to json.
The R to json conversion has an ambiguity on scalar vector conversions: R can't tell the difference between an "atomic vector of length 1" and "a scalar", while in json a scalar is
"just the value"and a vector of length 1 is represented in a list["just the value"].When our data frame has a list column, we need to resolve this ambiguity. For list-columns, in DT we need each item of the column to be itself a json list. This means that if the item already is a vector of length > 1, we have no trouble, but if the item is a scalar, we need to coerce it to a list to guarantee that the conversion behaves as expected. See the example:
Example:
Imagine in a two-row dataframe we have a list column with the following content:
list(c("a", "b"), "c"). Each element of this list column needs to become a list when converted to json. Naturally,c("a", "b")becomes["a", "b"], but what about"c"? It would become"c"and we need it to become["c"]instead.In R, both items
c("a", "b")and"c"are character vectors. We need to coerce the second to a list so x becomeslist(c("a", "b"), list("c"))and the conversion to json works as we require.The problem:
This coercion fails if the list column is not of type list, but a
vctrs::list_ofwith aptype=character(0)vector. In that scenario, when we try to turn "c" (a character vector) into list("c") (a list),vctrssteps in and tries to coerce the list back to a character, becausevctrs::list_ofenforces the character type to all elements of the list. This raises a coercion error as seen on #1180.The easiest solution in this case is to drop the
list_oftype if we need to, and leave the column as a regular list, so items may have mixed types in R -but will have homogeneous types in json!- and the assignment works without coercions from vctrs.Reprex in the associated issue #1180 .
I added a unit test to prevent regressions and updated the NEWS file.
Closes #1180