Skip to content

Commit 4c1409e

Browse files
committed
Tweak handling of nested data.frame conversion in toR()
1 parent 169b5d5 commit 4c1409e

File tree

3 files changed

+20
-12
lines changed

3 files changed

+20
-12
lines changed

_extensions/live/resources/live-runtime.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/interactive/data.qmd

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Data conversion is handled by the WebAssembly engine transparently, and most dat
1919
```{ojs}
2020
foo = [123, 456];
2121
bar = ({ x: [1, 2, 3], y: ["a", "b"], z: true });
22-
baz = [{ a: 1 }, { b: 2 }, { c: ["x", "y", "z"] }];
22+
baz = [{ a: 1 }, { b: ["x", "y", "z"], c: null }];
2323
```
2424

2525
::: {.panel-tabset}
@@ -50,7 +50,7 @@ print(baz)
5050
:::
5151

5252

53-
## Data frame conversion
53+
## R `data.frame` conversion
5454

5555
When using webR powered R blocks, D3 style JavaScript objects are specially handled and converted into `data.frame`s. For example, OJS ships with a built in dataset `alphabet`:
5656

live-runtime/src/environment.ts

+17-9
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,38 @@ export class WebREnvironmentManager {
2222
object if conversion fails.
2323
*/
2424
async toR(value: any): Promise<RObject> {
25-
if (isRObject(value)) return value;
25+
if (!value || isRObject(value)) return value;
2626

2727
const shelter = await this.shelter;
28-
if (value && value.constructor === Object) {
28+
if (value.constructor === Object) {
2929
try {
30-
value = await new shelter.RObject(value);
30+
return await new shelter.RObject(value);
3131
} catch (_e) {
3232
const e = _e as Error;
3333
if (!e.message.includes("Can't construct `data.frame`")) {
3434
throw e;
3535
}
36-
value = await new shelter.RList(value);
36+
return await new shelter.RList(
37+
Object.fromEntries(
38+
await Promise.all(Object.entries(value).map(async ([k, v]) => {
39+
return [k, await this.toR(v)];
40+
}))
41+
)
42+
);
3743
}
38-
} else if (value && value.constructor === Array) {
44+
}
45+
46+
if (value.constructor === Array) {
3947
try {
40-
value = await new shelter.RObject(value);
48+
return await new shelter.RObject(value);
4149
} catch (_e) {
4250
const e = _e as Error;
4351
if (!e.message.includes("Can't construct `data.frame`")) {
4452
throw e;
4553
}
46-
value = await Promise.all(value.map((v) => {
47-
return new shelter.RList(v);
48-
}));
54+
return await new shelter.RList(
55+
await Promise.all(value.map((v) => this.toR(v)))
56+
);
4957
}
5058
}
5159
return value;

0 commit comments

Comments
 (0)