Как я могу использовать purrr для извлечения атрибута в столбце глубоко вложенного списка в R? - PullRequest
2 голосов
/ 19 апреля 2020

Я использовал Google Geocoding API для запроса данных о местоположении для тысяч адресов. Содержание каждого запроса было проанализировано как список. Полученный список был добавлен в столбец «get_response».

У меня большие трудности при извлечении отдельных атрибутов из этих списков с помощью пакета purrr, и я надеялся, что вы, замечательные люди, могли бы помочь.

library(tidyverse)
#> Warning: package 'tidyverse' was built under R version 3.5.3

l1 <- list(results = list(list(geometry = list(location = list(lat = 41.9, lng = -87.6)))), status = "OK")
l2 <- list(results = list(list(geometry = list(location = list(lat = 35.1, lng = -70.6)))), status = "OK")

starting_df <- tribble(~name, ~get_response,
                     "first_location", l1,
                     "second_location", l2)
print(starting_df)
#> # A tibble: 2 x 2
#>   name            get_response    
#>   <chr>           <list>          
#> 1 first_location  <named list [2]>
#> 2 second_location <named list [2]>

Ниже я продемонстрирую, как я могу извлечь атрибут по одному:

pluck(starting_df[1,]$get_response, 1, "results", 1, "geometry", "location", "lat")
#> [1] 41.9
pluck(starting_df[2,]$get_response, 1, "results", 1, "geometry", "location", "lat")
#> [1] 35.1

Это мой желаемый вывод:

desired_output <- tribble(~name, ~get_response, ~lat,
                                  "first_location", l1, 41.9,
                                  "second_location", l2, 35.1)
print(desired_output)
#> # A tibble: 2 x 3
#>   name            get_response       lat
#>   <chr>           <list>           <dbl>
#> 1 first_location  <named list [2]>  41.9
#> 2 second_location <named list [2]>  35.1

Это моя попытка использовать purrr :: map

new_df <- mutate(starting_df, lat = map(get_response, pluck(1, "results", 1, "geometry", "location", "lat")))
#> Error: Can't convert NULL to function

Создано в 2020-04-18 пакетом Представить (v0.3.0)

Кто-нибудь знает хороший способ сделать это?

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

Мы можем использовать map из purrr

library(dplyr)
library(purrr)
starting_df %>%
    mutate(lat = map_dbl(get_response, ~ pluck(.x, 1, 1, 
             'geometry', 'location', 'lat', .default = NA_real_), 
              .default = NA_real_))
# A tibble: 2 x 3
#  name            get_response       lat
#  <chr>           <list>           <dbl>
#1 first_location  <named list [2]>  41.9
#2 second_location <named list [2]>  35.1

, оно также должно работать, когда некоторые элементы не имеют 'lat'

l3 <-  list(results = list(list(geometry = 
         list(location = list( lng = -70.6)))), status = "OK")

starting_df <- tribble(~name, ~get_response,
                      "first_location", l1,
                      "second_location", l2,  
                       "third_location", l3)
starting_df %>%
     mutate(lat = map_dbl(get_response, ~ pluck(.x, 1, 1, 
              'geometry', 'location', 'lat', .default = NA_real_), 
                .default = NA_real_))
# A tibble: 3 x 3
#  name            get_response       lat
#  <chr>           <list>           <dbl>
#1 first_location  <named list [2]>  41.9
#2 second_location <named list [2]>  35.1
#3 third_location  <named list [2]>  NA  

или другой вариант - rowwise из dplyr

starting_df %>% 
     rowwise %>%
     mutate(lat = pluck(get_response, 1, 1, 'geometry', 'location', 'lat'))
# A tibble: 2 x 3
# Rowwise: 
#  name            get_response       lat
#  <chr>           <list>           <dbl>
#1 first_location  <named list [2]>  41.9
#2 second_location <named list [2]>  35.1
1 голос
/ 19 апреля 2020

Вы можете использовать map_dbl из purrr и применить свой отрыв, используя формат формулы:

starting_df %>%
mutate(lat=map_dbl(get_response,~pluck(.x,"results",1,"geometry","location","lat")))

# A tibble: 2 x 3
  name            get_response       lat
  <chr>           <list>           <dbl>
1 first_location  <named list [2]>  41.9
2 second_location <named list [2]>  35.1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...