编辑随着我对问题的了解越来越多,我的问题发生了很大变化。在添加了几次编辑后,这篇文章变得难以处理,所以我从一个干净的石板和最后一个问题开始。
我正在尝试使用 R 通过 state Socrata 门户 下载犹他州的所有公共数据集。列出的记录超过 10,000 条,因此需要使用 scroll_id
参数的
深度滚动方法。在查询中使用此参数会按
resource.id
的字母顺序返回结果。但是,使用 NULL id 默认按字母顺序从第一个字母开始,并且不会返回所有结果,因为数千条记录以数字开头。
我的问题是:如何使用
scroll_id
参数进行查询,使其从数字最小的记录开始,而不是第一个字母?
我的解决方法是首先查询不带
scroll_id
参数的门户。这将以任意顺序返回 10,000 个结果。然后,我从该组中取出最低数字记录,并从那里进行深度滚动重新查询。这会产生我想象的“大多数”记录,但可能不是全部。我确信对于一个简单的问题来说这是一个荒谬的解决方法,但这是我正在使用的代码:
pacman::p_load(tidyverse,
httr,
jsonlite)
# Function to query without scroll_id
get_socrata_data <- function(domain,
limit = 15000) {
"http://api.us.socrata.com/api/catalog/v1?domains=${domain}&limit=${limit}" %>%
str_interp() %>%
httr::GET() %>%
content("text") %>%
fromJSON(flatten = TRUE)
}
# Scroll function that includes scroll_id
scroll_socrata <- function(domain,
limit = 15000,
scroll_id = NULL) {
"http://api.us.socrata.com/api/catalog/v1?domains=${domain}&scroll_id=${scroll_id}&limit=${limit}" %>%
str_interp() %>%
httr::GET() %>%
content("text") %>%
fromJSON(flatten = TRUE)
}
ut_domain <- 'opendata.utah.gov'
# Initial query without scroll_id
ut_results <- get_socrata_data(ut_domain)
nrow(ut_results$results)
# If results are capped, restart with first digit id using scroll function
if (nrow(ut_results$results) == 10000) {
# Pull out first record starting with digit
digit_start <- ut_results$results |>
filter(str_starts(resource.id, '\\d'))
first_digit_id <- first(sort(digit_start$resource.id))
# Data frame for results
output <- data.frame()
# Restart query with scroll_socrata function that includes scroll_id
page <- scroll_socrata(ut_domain,
scroll_id = first_digit_id)
output <- bind_rows(output, page$results)
# more pages if necessary
while (nrow(page$results) == 10000) {
page <- scroll_socrata(ut_domain,
scroll_id = last(page$results$resource.id))
output <- bind_rows(output, page$results)
}
}
# check total
nrow(output)
scroll_socrata <- function(domain,
limit = 15000,
scroll_id = NULL) {
"http://api.us.socrata.com/api/catalog/v1?domains=${domain}&scroll_id=${scroll_id}&limit=${limit}" %>%
str_interp() %>%
httr::GET() %>%
content("text") %>%
fromJSON(flatten = TRUE)
}
ut_domain <- 'opendata.utah.gov'
# DF for results
output <- data.frame()
# First query starting with lowest digit resource.id
page <- scroll_socrata(ut_domain,
limit = 15000,
scroll_id = '0')
output <- bind_rows(output, page$results)
# More pages if necessary
while (nrow(page$results) == 10000) {
page <- scroll_socrata(ut_domain,
limit = 15000,
scroll_id = last(page$results$resource.id))
output <- bind_rows(output, page$results)
}
output