-2

I am constructing a data frame from a (very deeply nested) json source.

I have successfully mapped the list elements I want to extract, and can almost! construct the tibble I want.

Except that some of the list elements are missing, if there is no data. Like so (I want the chr at position "five", and NA if it is missing, like in the second list):

nested_list  <- list(
    list(
        x = list(one = "this"),
        y = list(two = list(
                     three = list(
                           four = data_frame(
                                five = "is"))))),
   list(
       x = list(one = "a"),
       y = list(two = list(three = list()))))

How can I supply a fallback if the outer elements are missing? I'm fumbling around with map_if, but can't figure out a predicate function to test for presence of an element. I get

Error: Predicate functions must return a single `TRUE` or `FALSE`, not NULL

so far.

I think I have a reproducible example:

library("tidyverse")

nested_list  <- list(
    list(
        x = list(one = "this"),
        y = list(two = list(
                       three = list(
                               four = data_frame(
                                      five = "is"))))),
   list(
       x = list(one = "a"),
       y = list(two = list(three = list()))))

test_df <- nested_list %>%
    map(~ .x) %>%
    tibble(
        one = map_chr(., c("x", "one")),
        three = map_chr(., c("y", "two", "three", "four", "five"))
   )

this returns

Error: Result 2 must be a single string, not NULL of length 0

Where I'd like to just have a missing value in my final tibble.

reducing the tibble constructor to

test_df <- nested_list %>%
    map(~ .x) %>%
    tibble(
        one = map_chr(., c("x", "one")),
        three = map(., c("y", "two", "three"))
   )

gives me NULL values in the second row of the data frame; and, as expected, a nested list in the first row. `map_df(., c("one","two", "three", "four")) gives me uneven columns, and the tibble construction fails.

And my google fu is failing me.

1 Answers1

0

As I suspected, I was holding it wrong. There is a .null parameter to map, for just this purpose.

So:

test_df <- nested_list %>%
map(~ .x) %>%
tibble(
    one = map_chr(., c("x", "one")),
    three = map_chr(., c("y", "two", "three", "four", "five"), .null = NA_character_)
)

Works as expected.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92