knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(openalexR) library(dplyr)
The default output from an oa_fetch
call is a tibble.
This object type allows each row to be one unit of entity (article, institution, etc.), which is often helpful for downstream wrangling.
It simplifies and combines complex output elements in list columns, which can be extracted or exploded with dplyr::rowwise
or purrr::map
.
IMPORTANT: Although the list-to-tibble conversion can be trivial, in "flattening" the list output to a tibble, we took the opinionated approach and made a few decisions to simplify the original nested list such as retaining only a subset of the fields of Works (details in oa_df
source code).
If you think that everyone would benefit from an additional field being returned in the final dataframe, please open an issue.
While the tibble output is sufficient in most use cases, you may need to obtain the original nested list with all the information on an entity for your special research problem.
If so, please specify output = "list"
in your oa_fetch
call.
Then, you can wrangle the list output however you like, for example:
x <- oa_fetch( identifier = c("A5023888391", "A5042522694"), output = "list" ) d <- rrapply::rrapply(x, how = "melt") head(d)
Suppose we queried Open Alex to obtain information on large Canadian institutions and now want to extract their latitudes and longitudes.
institutions <- oa_fetch( entity = "institutions", country_code = "CA", cited_by_count = ">4000000", verbose = TRUE, count_only = FALSE ) head(institutions)
We present three different approaches below.
The use of rowwise
used to be discouraged, but the tidyverse team has now recognized its importance in many workflows, and so rowwise
is here to stay.
We think rowwise
pairs very naturally with our list columns output.
institutions %>% rowwise() %>% mutate( name = display_name, openalex = stringr::str_extract(id, "I\\d+"), lat = geo$latitude, lon = geo$longitude, .keep = "none" )
Alternatively, you can use any function in the purrr::map
family.
As you can see below, the syntax is a little less natural, but you may gain some performance advantage if you have a really large dataframe.
institutions %>% mutate( name = display_name, openalex = stringr::str_extract(id, "I\\d+"), lat = purrr::map_dbl(geo, ~ .x$latitude), lon = purrr::map_dbl(geo, ~ .x$longitude), .keep = "none" )
Similar to the purrr approach, you can use the base functions in the lapply
family, for example:
institutions %>% mutate( name = display_name, openalex = stringr::str_extract(id, "I\\d+"), lat = vapply(geo, function(x) x$latitude, numeric(1)), lon = vapply(geo, function(x) x$longitude, numeric(1)), .keep = "none" )
Suppose we have a tibble of works output and would like to find the institutions corresponding with the works' authors. In this case, each work may have more than one affiliated institutions.
Assuming that each author is affiliated with only one institution, we can call oa_fetch
with the default output = "tibble"
:
works <- oa_fetch( entity = "works", title.search = c("bibliometric analysis", "science mapping"), cited_by_count = ">100", from_publication_date = "2020-01-01", to_publication_date = "2021-01-31", options = list(sort = "cited_by_count:desc"), count_only = FALSE )
We will store the result in a list column:
multi_insts <- works %>% rowwise() %>% mutate( openalex = stringr::str_extract(id, "W\\d+"), institutions = list(unique(authorships$institution_display_name)), .keep = "none" ) multi_insts # institutions of the first work str(multi_insts[1, "institutions"])
If we want to get all the institutions that the authors of these works are affiliated with (since one author may be affiliated with more than one institution), you would want to work with the list output.
As you can see, the nested list can be more convoluted to work with:
works_list <- oa_fetch( entity = "works", title.search = c("bibliometric analysis", "science mapping"), cited_by_count = ">100", from_publication_date = "2020-01-01", to_publication_date = "2021-01-31", options = list(sort = "cited_by_count:desc"), output = "list" ) work_authors <- lapply(works_list, \(x) x$authorships) unique_insts <- sapply( work_authors, \(z) unique(unlist( sapply( z, \(y) sapply(y$institutions, \(x) x$display_name) ) )) ) unique_insts[[1]]
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.