@@ -65,12 +65,11 @@ extract_metadata_from_doi <- function(doi, file_path, write_output = TRUE){
6565extract_metadata_oa <- function (doi ){
6666
6767 assertthat :: assert_that(assertthat :: is.string(doi ),msg = " doi must be a non-vector string" )
68+ cli :: cli_alert(" Starting now, at {Sys.time()}" )
6869
69- # doi.org/10.1038/s41597-025-05332-x
70- oa_url <- sprintf(" https://api.openalex.org/works/%s" ,doi )
70+ work_json <- download_oa_item(oa_id = doi , entity = " works" ,sleep_time = 0 )
7171
72- oa_json <- jsonlite :: fromJSON(txt = oa_url )
73- oa_json $ authorships $ affiliations
72+ oa_json <- jsonlite :: fromJSON(txt = work_json )
7473
7574 # Name Jane Doe
7675 # Given Name Jane
@@ -94,24 +93,24 @@ extract_metadata_oa<-function(doi){
9493 creator_df $ `Name Identifier` <- creators $ author $ orcid
9594
9695 # get affiliation string and identifier
97-
9896 aff_df <- creators $ affiliations | >
9997 purrr :: map_df(function (x ){
98+
10099 raw_affiliation <- x $ raw_affiliation_string [[1 ]]
101100
102101 oa_inst_id <- x $ institution_ids [[1 ]][1 ] | >
103102 fs :: path_file()
104103
105- oa_inst_api <- sprintf(" https://api.openalex.org/institutions/%s" , oa_inst_id )
106-
107- oa_inst_list <- jsonlite :: fromJSON(oa_inst_api )
104+ inst_json <- download_oa_item(oa_id = oa_inst_id ,entity = " institutions" )
108105
109- oa_inst_list $ ror
106+ oa_inst_list <- jsonlite :: fromJSON( txt = inst_json )
110107
111108 out <- data.frame (" Affiliation" = raw_affiliation , " Affiliation Identifier" = oa_inst_list $ ror )
112109
110+ # rate limiting downloads
111+
113112 return (out )
114- })
113+ }, .progress = " Getting Affiliations " )
115114
116115 creator_df_tidy <- cbind(creator_df ,aff_df ) | >
117116 dplyr :: rename(" Affiliation Identifier" = .data $ Affiliation.Identifier )
@@ -141,15 +140,17 @@ Award Title Verena Fellow-in-Residence Award"
141140
142141 funder_references_tidy <- oa_json $ grants | >
143142 dplyr :: mutate(oa_funder_id = fs :: path_file(.data $ funder )) | >
144- dplyr :: mutate(oa_funder_api = sprintf(" https://api.openalex.org/funders/%s" , .data $ oa_funder_id )) | >
145- dplyr :: mutate(funder_identifier = purrr :: map_chr(.data $ oa_funder_api , function (x ){
146- funder_json <- jsonlite :: fromJSON(x )
143+ dplyr :: mutate(funder_identifier = purrr :: map_chr(.data $ oa_funder_id , function (x ){
144+ funder_file <- download_oa_item(oa_id = x ,entity = " funders" )
145+
146+ # rate limiting downloads to 10 per second
147+ funder_json <- jsonlite :: fromJSON(funder_file )
147148 funder_ids <- funder_json $ ids
148149 # use one of ror, crossref doi, or openalex id
149150 ids_ordered <- c(" ror" ," doi" ," wikidata" ," openalex" )
150151 preferred_id <- which(ids_ordered %in% names(funder_ids ))[1 ]
151152 funder_ids [ids_ordered [preferred_id ]][[1 ]]
152- })
153+ }, .progress = " Getting Funder Info " )
153154 ) | >
154155 dplyr :: select(dplyr :: all_of(c(" funder_display_name" ," funder_identifier" ," award_id" ))) | >
155156 dplyr :: rename(" Funder Name" = " funder_display_name" ,
@@ -272,3 +273,47 @@ make_simple_df <- function(property,value){
272273 out <- data.frame (Group = property ,Variable = property , Value = value )
273274 return (out )
274275}
276+
277+ # ' Rate limited download of OA items
278+ # '
279+ # ' Checks if file exists in a directory, downloads the file if its not found.
280+ # ' Sleeps for a given amount of time to respect rate limits on openalex servers.
281+ # '
282+ # ' @param entity Character. What kind of openalex item is it?
283+ # ' @param oa_id Character. ID from openalex
284+ # ' @param dir_temp Character. path to directory where jons is stored.
285+ # ' @param sleep_time Numeric. Seconds of sleep.
286+ # '
287+ # ' @returns Character. File path to json file
288+ # ' @family Project Metadata
289+ download_oa_item <- function (entity ,oa_id , dir_temp = tempdir(),sleep_time = 1 ){
290+
291+ entities <- c(" works" ," institutions" ," funders" ," authors" ," sources" ," topics"
292+ ," publishers" )
293+
294+ msg <- sprintf(" Entity must be one of:\n %s" , paste(entities ,collapse = " \n " ))
295+
296+ assertthat :: assert_that(entity %in% entities ,msg = msg )
297+ assertthat :: assert_that( assertthat :: is.string(oa_id ),msg = " oa_id must be character" )
298+ assertthat :: assert_that(fs :: dir_exists(dir_temp ), msg = " dir_temp must exist" )
299+ assertthat :: assert_that(assertthat :: is.number(sleep_time ), msg = " sleep_time must be numeric and scalar" )
300+
301+ # # normalize the inputs so it handles dois appropriately
302+ file_id <- rlang :: hash(x = oa_id )
303+
304+ oa_json <- sprintf(" %s/%s.json" ,dir_temp ,file_id )
305+ oa_api <- sprintf(" https://api.openalex.org/%s/%s" ,entity , oa_id )
306+
307+
308+
309+ # if the file doesnt exist, get it
310+ if (! fs :: file_exists(oa_json )){
311+ curl :: curl_download(url = oa_api ,destfile = oa_json )
312+ Sys.sleep(sleep_time )
313+ }
314+
315+ return (oa_json )
316+
317+ }
318+
319+
0 commit comments