[英]How to use an API in R to be able to get data for storing into a db?
我試圖弄清楚如何在 R 中獲取數據,以便將其制作成可以存儲到 sql 等數據庫中的表。
API <- "https://covidtrackerapi.bsg.ox.ac.uk/api/v2/stringency/date-range/{2020-01-01}/{2020-06-30}"
oxford_covid <- GET(API)
然后我嘗試解析這些數據並將其轉換為 dataframe 但是當我這樣做時出現以下錯誤:“錯誤:第 4、5、6、7、8 和 178 列必須命名。使用.name_repair 來指定修理。” 和“錯誤:Tibble 列必須具有兼容的大小。* 大小 2:列deaths
、 casesConfirmed
和stringency
。* 大小 176:列..2020.12.27
、 ..2020.12.28
、 ..2020.12.29
和”
我不確定是否有更好的方法或如何解析它。 有沒有方法或方法? 我在網上運氣不太好。
看起來您正在嘗試從 API 返回 JSON 並調用read.table
或其他東西。 不要那樣做,JSON 應該由 JSON 工具(例如jsonlite::parse_json
)解析。
URL 的一些工作。
js <- jsonlite::parse_json(url("https://covidtrackerapi.bsg.ox.ac.uk/api/v2/stringency/date-range/2020-01-01/2020-06-30"))
lengths(js)
# scale countries data
# 3 183 182
str(js, max.level = 2, list.len = 3)
# List of 3
# $ scale :List of 3
# ..$ deaths :List of 2
# ..$ casesConfirmed:List of 2
# ..$ stringency :List of 2
# $ countries:List of 183
# ..$ : chr "ABW"
# ..$ : chr "AFG"
# ..$ : chr "AGO"
# .. [list output truncated]
# $ data :List of 182
# ..$ 2020-01-01:List of 183
# ..$ 2020-01-02:List of 183
# ..$ 2020-01-03:List of 183
# .. [list output truncated]
所以這個比較大。 由於您希望使用data.frame
,因此我將僅查看js$data
; js$countries
看起來比較無趣,
str(unlist(js$countries))
# chr [1:183] "ABW" "AFG" "AGO" "ALB" "AND" "ARE" "ARG" "AUS" "AUT" "AZE" "BDI" "BEL" "BEN" "BFA" "BGD" "BGR" "BHR" "BHS" "BIH" "BLR" "BLZ" "BMU" "BOL" "BRA" "BRB" "BRN" "BTN" "BWA" "CAF" "CAN" "CHE" "CHL" "CHN" "CIV" "CMR" "COD" "COG" "COL" "CPV" ...
並且與js$data
無關。 js$scale
可能很有趣,但我現在將跳過它。
我第一次將這樣的數據加入data.frame
是以下之一,具體取決於您對 R 方言的偏好:
do.call(rbind.data.frame, list_of_frames) # base R
dplyr::bind_rows(list_of_frames) # tidyverse
data.table::rbindlist(list_of_frames) # data.table
但是我們會遇到問題。 也就是說,有些條目是NULL
,而 R 更喜歡它們是某物(例如NA
)。
str(js$data[[1]][1])
# List of 2
# $ ABW:List of 8
# ..$ date_value : chr "2020-01-01"
# ..$ country_code : chr "ABW"
# ..$ confirmed : NULL # <--- problem
# ..$ deaths : NULL
# ..$ stringency_actual : int 0
# ..$ stringency : int 0
# ..$ stringency_legacy : int 0
# ..$ stringency_legacy_disp: int 0
因此,我們需要遍歷其中的每一個並將NULL
替換為NA
。 不幸的是,我不知道有一個簡單的工具可以通過列表列表遞歸 go(甚至rapply
在我的測試中也不能很好地工作),所以我們在這里使用三重lapply
有點蠻力:
長話短說,
str(js$data[[1]][[1]])
# List of 8
# $ date_value : chr "2020-01-01"
# $ country_code : chr "ABW"
# $ confirmed : NULL
# $ deaths : NULL
# $ stringency_actual : int 0
# $ stringency : int 0
# $ stringency_legacy : int 0
# $ stringency_legacy_disp: int 0
jsdata <-
lapply(js$data, function(z) {
lapply(z, function(y) {
lapply(y, function(x) if (is.null(x)) NA else x)
})
})
str(jsdata[[1]][[1]])
# List of 8
# $ date_value : chr "2020-01-01"
# $ country_code : chr "ABW"
# $ confirmed : logi NA
# $ deaths : logi NA
# $ stringency_actual : int 0
# $ stringency : int 0
# $ stringency_legacy : int 0
# $ stringency_legacy_disp: int 0
(從技術上講,如果我們知道它將是整數,我們應該使用NA_integer_
。幸運的是,R 及其方言能夠使用這個快捷方式,我們稍后會看到。)
之后,我們可以進行雙重綁定並回到我之前討論的框架制作步驟。 選擇以下選項之一,無論您喜歡哪種方言:
alldat <- do.call(rbind.data.frame,
lapply(jsdata, function(z) do.call(rbind.data.frame, z)))
alldat <- dplyr::bind_rows(purrr::map(jsdata, dplyr::bind_rows))
alldat <- data.table::rbindlist(lapply(jsdata, data.table::rbindlist))
為簡單起見,我將展示第一個(基本 R)版本:
tail(alldat)
# date_value country_code confirmed deaths stringency_actual stringency stringency_legacy stringency_legacy_disp
# 2020-06-30.AND 2020-06-30 AND 855 52 42.59 42.59 65.47 65.47
# 2020-06-30.ARE 2020-06-30 ARE 48667 315 72.22 72.22 83.33 83.33
# 2020-06-30.AGO 2020-06-30 AGO 284 13 75.93 75.93 83.33 83.33
# 2020-06-30.ALB 2020-06-30 ALB 2535 62 68.52 68.52 78.57 78.57
# 2020-06-30.ABW 2020-06-30 ABW 103 3 47.22 47.22 63.09 63.09
# 2020-06-30.AFG 2020-06-30 AFG 31507 752 78.70 78.70 76.19 76.19
如果你對$scale
感到好奇,
do.call(rbind.data.frame, js$scale)
# min max
# deaths 0 127893
# casesConfirmed 0 2633466
# stringency 0 100
## or
data.table::rbindlist(js$scale, idcol="id")
# id min max
# <char> <int> <int>
# 1: deaths 0 127893
# 2: casesConfirmed 0 2633466
# 3: stringency 0 100
## or
dplyr::bind_rows(js$scale, .id = "id")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.