Google Places API и R - вызов 2-го столбца во фрейме данных возвращает шесть отдельных столбцов
Я пытаюсь сохранить результаты фрейма данных, извлеченного из списка через API Google Адресов. Мой звонок в API...
library(googleway)
HAVE_PLACES <- google_places(search_string = "grocery store",
location = c(35.4168, -80.5883),
radius = 10000, key = key)
... возвращает объект списка HAVE_PLACES
:
Третий объект в этом списке - results
- это фрейм данных с одним наблюдением для каждого местоположения, полученного в вызове API. Когда я звоню View(HAVE_PLACES$results)
, Я получаю то, что выглядит как набор векторов - как я ожидаю, глядя на кадр данных...
... Но похоже, что фрейм данных включает в себя фреймы данных:
ЧТО ПРОИСХОДИТ ЗДЕСЬ?
Более конкретно:
- Как фрейм данных может содержать фреймы данных и почему
View()
показать вложенные фреймы данных, как это было бы векторам? - При работе с данными этого типа, где вы хотите столбцы, которые вы видите в
View()
просто быть векторами - для манипуляций и экспорта - есть ли лучшие практики? Я собираюсь преобразовать каждый вектор этого предполагаемого фрейма данных под названиемgeometry
на отдельные объекты, иcbind()
результаты кHAVE_PLACES$results
, Но это кажется безумным.
1 ответ
Акрун прав (как обычно!). Data.frame может иметь списки в виде "столбцов". Это нормальное поведение.
Ваш вопрос, кажется, является более общим вопросом о том, как извлечь данные из вложенного списка в R, но на примере ответа API Google. Учитывая, что вы используете googleway
(Я автор pacakge), я отвечаю на это в контексте ответа Google. Тем не менее, есть множество других ответов и примеров в Интернете о том, как работать со списками в R.
объяснение
Вы видите вложенные списки в своих результатах, потому что данные, возвращаемые из API Google, на самом деле являются JSON. google_places()
функция "упрощает" это до data.frame
с помощью jsonlite::fromJSON()
внутренне.
Если вы установите simplify = F
в вызове функции вы можете увидеть необработанный вывод JSON
library(googleway)
set_key("GOOGLE_API_KEY")
HAVE_PLACES_JSON <- google_places(search_string = "grocery store",
location = c(35.4168, -80.5883),
radius = 10000,
simplify = F)
## run this to view the JSON.
jsonlite::prettify(paste0(HAVE_PLACES_JSON))
Вы увидите, что JSON может содержать много вложенных объектов. Когда преобразовано в R data.frame
эти вложенные объекты возвращаются как столбцы списка
Если вы не знакомы с JSON, возможно, стоит немного изучить, чтобы понять, в чем дело.
Извлечение данных
Я написал несколько функций для извлечения полезной информации из ответов API, которые могут быть полезны здесь
locations <- place_location(HAVE_PLACES)
head(locations)
# lat lng
# 1 35.38690 -80.55993
# 2 35.42111 -80.57277
# 3 35.37006 -80.66360
# 4 35.39793 -80.60813
# 5 35.44328 -80.62367
# 6 35.37034 -80.54748
placenames <- place_name(HAVE_PLACES)
head(placenames)
# "Food Lion" "Food Lion" "Food Lion" "Food Lion" "Food Lion" "Food Lion"
Тем не менее, обратите внимание, что вы все равно получите некоторые объекты списка, потому что в этом случае у "местоположения" может быть много "типов"
placetypes <- place_type(HAVE_PLACES)
str(placetypes)
# List of 20
# $ : chr [1:5] "grocery_or_supermarket" "store" "food" "point_of_interest" ...
# $ : chr [1:5] "grocery_or_supermarket" "store" "food" "point_of_interest" ...
# $ : chr [1:5] "grocery_or_supermarket" "store" "food" "point_of_interest" ...
# $ : chr [1:5] "grocery_or_supermarket" "store" "food" "point_of_interest" ...
Резюме
С помощью ответов API Google вам нужно будет извлечь нужные элементы данных и создать их в нужном вам объекте.
df <- cbind(
place_name(HAVE_PLACES)
, place_location(HAVE_PLACES)
, place_type(HAVE_PLACES)[[1]] ## only selecting the 1st 'type'
)
head(df)
# place_name(HAVE_PLACES) lat lng place_type(HAVE_PLACES)[[1]]
# 1 Food Lion 35.38690 -80.55993 grocery_or_supermarket
# 2 Food Lion 35.42111 -80.57277 store
# 3 Food Lion 35.37006 -80.66360 food
# 4 Food Lion 35.39793 -80.60813 point_of_interest
# 5 Food Lion 35.44328 -80.62367 establishment
# 6 Food Lion 35.37034 -80.54748 grocery_or_supermarket