├── .github ├── .gitignore ├── dependabot.yml └── workflows │ └── R-CMD-check.yaml ├── _pkgdown.yml ├── LICENSE ├── .gitignore ├── docs ├── pkgdown.yml ├── link.svg ├── bootstrap-toc.css ├── docsearch.js ├── pkgdown.js ├── authors.html ├── LICENSE-text.html ├── 404.html ├── bootstrap-toc.js ├── reference │ ├── S2_fields.html │ ├── semanticscholar-package.html │ ├── S2_api.html │ ├── S2_ratelimit.html │ ├── S2_attribution.html │ ├── S2_author.html │ ├── S2_search_papers.html │ ├── S2_paper.html │ ├── zotero_references.html │ ├── S2_paper2.html │ ├── index.html │ └── S2_author2.html ├── LICENSE.html ├── pkgdown.css ├── docsearch.css └── index.html ├── tests ├── testthat.R └── testthat │ ├── test-zotero.R │ ├── test-S2.R │ └── test-S2_v2.R ├── .Rbuildignore ├── man ├── S2_fields.Rd ├── S2_api.Rd ├── semanticscholar-package.Rd ├── S2_ratelimit.Rd ├── S2_author.Rd ├── S2_attribution.Rd ├── zotero_references.Rd ├── S2_search_papers.Rd ├── S2_paper2.Rd ├── S2_paper.Rd └── S2_author2.Rd ├── R ├── package-semanticscholar.R ├── zotero_references.R └── api.R ├── semanticscholar.Rproj ├── NAMESPACE ├── LICENSE.md ├── DESCRIPTION ├── data-raw └── author_search.R ├── README.Rmd └── README.md /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | destination: docs 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2020 2 | COPYRIGHT HOLDER: Markus Skyttner 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | 6 | /.quarto/ 7 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 2.11.4 2 | pkgdown: 1.6.1 3 | pkgdown_sha: ~ 4 | articles: {} 5 | last_built: 2021-08-17T07:59Z 6 | 7 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(semanticscholar) 3 | 4 | #Sys.setenv(CI = TRUE) 5 | #Sys.setenv(CI = "false") 6 | 7 | test_check("semanticscholar") 8 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^README\.Rmd$ 4 | ^_pkgdown\.yml$ 5 | ^docs$ 6 | ^pkgdown$ 7 | ^data-raw$ 8 | ^LICENSE\.md$ 9 | ^\.github$ 10 | -------------------------------------------------------------------------------- /man/S2_fields.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/api.R 3 | \name{S2_fields} 4 | \alias{S2_fields} 5 | \title{Valid fields available for use in API calls} 6 | \usage{ 7 | S2_fields() 8 | } 9 | \description{ 10 | Valid fields available for use in API calls 11 | } 12 | -------------------------------------------------------------------------------- /R/package-semanticscholar.R: -------------------------------------------------------------------------------- 1 | #' Data from Semantic Scholar for use in R 2 | #' 3 | #' This package provides on-demand data access to [Semantic Scholar](https://semanticscholar.org) 4 | #' through a lightweight API for author and publication data. 5 | #' 6 | #' @aliases semanticscholar 7 | #' @name semanticscholar-package 8 | #' @keywords package 9 | NULL 10 | -------------------------------------------------------------------------------- /man/S2_api.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/api.R 3 | \name{S2_api} 4 | \alias{S2_api} 5 | \title{Endpoint used for requests to Semantic Scholar API} 6 | \usage{ 7 | S2_api() 8 | } 9 | \description{ 10 | When environment variable SEMANTICSCHOLAR_API is set to a valid API key this 11 | value differs as endpoints allowing higher rate limits are being used. 12 | } 13 | -------------------------------------------------------------------------------- /man/semanticscholar-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/package-semanticscholar.R 3 | \name{semanticscholar-package} 4 | \alias{semanticscholar-package} 5 | \alias{semanticscholar} 6 | \title{Data from Semantic Scholar for use in R} 7 | \description{ 8 | This package provides on-demand data access to \href{https://semanticscholar.org}{Semantic Scholar} 9 | through a lightweight API for author and publication data. 10 | } 11 | \keyword{package} 12 | -------------------------------------------------------------------------------- /semanticscholar.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /man/S2_ratelimit.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/api.R 3 | \name{S2_ratelimit} 4 | \alias{S2_ratelimit} 5 | \title{Rate limit for API calls} 6 | \usage{ 7 | S2_ratelimit() 8 | } 9 | \description{ 10 | The minimum interval in seconds between requests to the API. 11 | } 12 | \details{ 13 | When environment variable SEMANTICSCHOLAR_API is set to a valid API key this 14 | value can be approx 0.01 (for 100 requests per second) but if no API key is 15 | used, the default value will be around 3.5 (allowing a maximum of 100 requests per 5 minutes) 16 | } 17 | -------------------------------------------------------------------------------- /man/S2_author.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/api.R 3 | \name{S2_author} 4 | \alias{S2_author} 5 | \title{Retrieve author information} 6 | \usage{ 7 | S2_author(S2AuthorId) 8 | } 9 | \arguments{ 10 | \item{S2AuthorId}{string with author identifier} 11 | } 12 | \value{ 13 | list representing author object 14 | } 15 | \description{ 16 | This function retrieves Semantic Scholar data for 17 | an author given the S2Author identifier 18 | } 19 | \details{ 20 | Example of Accessible Paper Identifiers: 21 | \itemize{ 22 | \item S2 Author ID : 1741101 23 | } 24 | } 25 | \examples{ 26 | \dontrun{ 27 | S2_author(1741101) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(S2_api) 4 | export(S2_attribution) 5 | export(S2_author) 6 | export(S2_author2) 7 | export(S2_fields) 8 | export(S2_paper) 9 | export(S2_paper2) 10 | export(S2_ratelimit) 11 | export(S2_search_papers) 12 | export(zotero_references) 13 | importFrom(dplyr,`%>%`) 14 | importFrom(dplyr,as_tibble) 15 | importFrom(dplyr,mutate) 16 | importFrom(dplyr,select) 17 | importFrom(dplyr,tibble) 18 | importFrom(httr,GET) 19 | importFrom(httr,content) 20 | importFrom(httr,status_code) 21 | importFrom(humaniformat,parse_names) 22 | importFrom(jsonlite,fromJSON) 23 | importFrom(purrr,map) 24 | importFrom(purrr,possibly) 25 | importFrom(rlang,.data) 26 | -------------------------------------------------------------------------------- /man/S2_attribution.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/api.R 3 | \name{S2_attribution} 4 | \alias{S2_attribution} 5 | \title{Attribution} 6 | \usage{ 7 | S2_attribution() 8 | } 9 | \description{ 10 | Use this attribution whenever data from the API is publicly displayed 11 | } 12 | \details{ 13 | Semantic Scholar provides a RESTful API for convenient linking 14 | to Semantic Scholar pages and pulling information about individual records 15 | on demand. When publicly displaying data from this API, 16 | please incorporate the Semantic Scholar name and logo and point back to 17 | Semantic Scholar at https://www.semanticscholar.org/ with 18 | a utm_source=api UTM parameter. 19 | } 20 | -------------------------------------------------------------------------------- /tests/testthat/test-zotero.R: -------------------------------------------------------------------------------- 1 | test_that("assembling references for use in Zotero works", { 2 | skip_on_ci() 3 | 4 | # TODO: fix this 5 | 6 | # # get data from several identifiers for importing into Zotero 7 | # ids <- c("10.1038/nrn3241", "CorpusID:37220927") 8 | # my_refs <- zotero_references(ids) 9 | 10 | # # this data can now be imported via the Zotero API using https://github.com/giocomai/zoteroR 11 | # # showing data form the first record 12 | # my_refs[[1]]$journalArticle %>% glimpse() 13 | # my_refs[[2]]$creators %>% knitr::kable() 14 | 15 | ids <- c("10.1038/nrn3241", "CorpusID:37220927") 16 | refs <- zotero_references(ids) 17 | is_valid <- length(refs) == 2 18 | expect_true(is_valid) 19 | }) 20 | -------------------------------------------------------------------------------- /man/zotero_references.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/zotero_references.R 3 | \name{zotero_references} 4 | \alias{zotero_references} 5 | \title{References for zotero} 6 | \usage{ 7 | zotero_references(identifiers) 8 | } 9 | \arguments{ 10 | \item{identifiers}{a character vector of identifiers} 11 | } 12 | \value{ 13 | a list with results 14 | } 15 | \description{ 16 | Given a vector of identifiers, extract data for use in Zotero 17 | } 18 | \details{ 19 | See https://github.com/giocomai/zoteroR for working with Zotero from R 20 | } 21 | \examples{ 22 | \dontrun{ 23 | if(interactive()){ 24 | ids <- c("10.1038/nrn3241", "CorpusID:37220927") 25 | zotero_references(ids) 26 | } 27 | } 28 | } 29 | \seealso{ 30 | \code{\link[humaniformat]{parse_names}} 31 | } 32 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /man/S2_search_papers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/api.R 3 | \name{S2_search_papers} 4 | \alias{S2_search_papers} 5 | \title{This function retrieves Semantic Scholar data for 6 | a keyword search} 7 | \usage{ 8 | S2_search_papers(keyword, offset = 0, limit = 10, fields = NULL) 9 | } 10 | \arguments{ 11 | \item{keyword}{string with keywords to search for, supports AND and OR and 12 | inclusion and exclusion of terms, for example "+Epidemic +Modeling +Canada -COVID"} 13 | 14 | \item{offset}{integer paging offset} 15 | 16 | \item{limit}{integer paging length} 17 | 18 | \item{fields}{extra fields to include, for example "title,authors"} 19 | } 20 | \value{ 21 | list representing paper objects 22 | } 23 | \description{ 24 | This function retrieves Semantic Scholar data for 25 | a keyword search 26 | } 27 | \examples{ 28 | \dontrun{ 29 | S2_search_papers(keyword = "literature graph") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /man/S2_paper2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/api.R 3 | \name{S2_paper2} 4 | \alias{S2_paper2} 5 | \title{This function retrieves details about a paper's authors} 6 | \usage{ 7 | S2_paper2( 8 | identifier, 9 | details = c("authors", "citations", "references"), 10 | offset = 0, 11 | limit = 10, 12 | fields = NULL 13 | ) 14 | } 15 | \arguments{ 16 | \item{identifier}{string with keywords to search for} 17 | 18 | \item{details}{one of "authors", "citations" or "references"} 19 | 20 | \item{offset}{integer paging offset} 21 | 22 | \item{limit}{integer paging length} 23 | 24 | \item{fields}{extra fields to include, for example "title,authors"} 25 | } 26 | \value{ 27 | list representing paper objects 28 | } 29 | \description{ 30 | This function retrieves details about a paper's authors 31 | } 32 | \examples{ 33 | \dontrun{ 34 | S2_paper2(identifier = "649def34f8be52c8b66281af98ae884c09aef38b") 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/testthat/test-S2.R: -------------------------------------------------------------------------------- 1 | test_that("Getting data for a paper works", { 2 | skip_on_ci() 3 | 4 | r1 <- 5 | S2_paper( 6 | identifier = "arXiv:1705.10311", 7 | include_unknown_refs = TRUE 8 | ) 9 | 10 | is_valid <- r1$paperId == "47be321bff23f73c71d7e5716cd107ead087c3ae" 11 | expect_true(is_valid) 12 | }) 13 | 14 | test_that("Getting data for some papers works", { 15 | skip_on_ci() 16 | 17 | identifiers <- c( 18 | "0796f6cd7f0403a854d67d525e9b32af3b277331", 19 | "10.1038/nrn3241", 20 | "arXiv:1705.10311", 21 | "MAG:112218234", 22 | "ACL:W12-3903", 23 | "PMID:19872477", 24 | "CorpusID:37220927" 25 | ) 26 | 27 | pid <- function(x) { 28 | Sys.sleep(S2_ratelimit()) 29 | S2_paper(x)$paperId 30 | } 31 | ids <- vapply(identifiers, pid, character(1)) 32 | is_valid <- all(nchar(ids) == 40) 33 | 34 | expect_true(is_valid) 35 | }) 36 | 37 | test_that("Getting data for an author works", { 38 | skip_on_ci() 39 | r1 <- S2_author("1741101") 40 | is_valid <- r1$authorId == "1741101" 41 | expect_true(is_valid) 42 | }) 43 | -------------------------------------------------------------------------------- /man/S2_paper.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/api.R 3 | \name{S2_paper} 4 | \alias{S2_paper} 5 | \title{Retrieve paper information} 6 | \usage{ 7 | S2_paper(identifier, include_unknown_refs = FALSE) 8 | } 9 | \arguments{ 10 | \item{identifier}{string with identifier} 11 | 12 | \item{include_unknown_refs}{logical, Default: FALSE} 13 | } 14 | \value{ 15 | list representing S2 paper object 16 | } 17 | \description{ 18 | This function retrieves Semantic Scholar data for a paper 19 | given its identifier 20 | } 21 | \details{ 22 | Example of Accessible Paper Identifiers: 23 | \itemize{ 24 | \item S2 Paper ID : 0796f6cd7f0403a854d67d525e9b32af3b277331 25 | \item DOI : 10.1038/nrn3241 26 | \item ArXiv ID : arXiv:1705.10311 27 | \item MAG ID : MAG:112218234 28 | \item ACL ID : ACL:W12-3903 29 | \item PubMed ID : PMID:19872477 30 | \item Corpus ID : CorpusID:37220927 31 | } 32 | 33 | S2 is an abbreviation for Semantic Scholar 34 | MAG is an abbreviation for Microsoft Academic Graph 35 | } 36 | \examples{ 37 | \dontrun{ 38 | S2_paper("fb5d1bb23724d9a5a5eae036a2e3cf291cac2c1b") 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2020 Markus Skyttner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /man/S2_author2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/api.R 3 | \name{S2_author2} 4 | \alias{S2_author2} 5 | \title{This function retrieves Semantic Scholar data for 6 | an author given the S2Author identifier} 7 | \usage{ 8 | S2_author2( 9 | S2AuthorId, 10 | details = c("papers"), 11 | offset = 0, 12 | limit = 10, 13 | fields = NULL 14 | ) 15 | } 16 | \arguments{ 17 | \item{S2AuthorId}{string with author identifier} 18 | 19 | \item{details}{one of "authors", "citations" or "references"} 20 | 21 | \item{offset}{integer paging offset} 22 | 23 | \item{limit}{integer paging length} 24 | 25 | \item{fields}{extra fields to include, for example "title,authors"} 26 | } 27 | \value{ 28 | list representing author object 29 | } 30 | \description{ 31 | This function retrieves Semantic Scholar data for 32 | an author given the S2Author identifier 33 | } 34 | \details{ 35 | Example of Accessible Paper Identifiers: 36 | \itemize{ 37 | \item S2 Author ID : 1681232 38 | } 39 | } 40 | \examples{ 41 | \dontrun{ 42 | S2_author(1681232) 43 | S2_author2(1681232, fields="affiliations,aliases,externalIds") 44 | S2_author2(1681232, fields="paperId,externalIds", details = "papers", offset=0, limit = 100) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: semanticscholar 2 | Type: Package 3 | Title: Data From Semantic Scholar Leightweight API 4 | Version: 0.2.1 5 | Authors@R: 6 | person(given = "Markus", 7 | family = "Skyttner", 8 | role = c("cre", "aut"), 9 | email = "markussk@kth.se") 10 | Description: Semantic Scholar is a free, non-profit, AI-powered academic search and 11 | discovery engine whose mission is to empower researchers. It can be used as a 12 | research tool for scientific literature available and is available at 13 | https://semanticscholar.org. It provides a RESTful API for convenient linking 14 | to Semantic Scholar pages and pulling information about individual records on demand. 15 | This R package wraps the lightweight API in order to facilitate on demand access 16 | to records in this data source. 17 | License: MIT + file LICENSE 18 | URL: https://github.com/KTH-Library/semanticscholar 19 | BugReports: https://github.com/KTH-Library/semanticscholar/issues 20 | Encoding: UTF-8 21 | LazyData: true 22 | Imports: 23 | dplyr, 24 | jsonlite, 25 | httr, 26 | humaniformat, 27 | rlang, 28 | purrr 29 | Roxygen: list(markdown = TRUE) 30 | RoxygenNote: 7.3.2 31 | Suggests: 32 | testthat 33 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | 8 | name: R-CMD-check.yaml 9 | 10 | permissions: read-all 11 | 12 | jobs: 13 | R-CMD-check: 14 | runs-on: ${{ matrix.config.os }} 15 | 16 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 17 | 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | config: 22 | - {os: macos-latest, r: 'release'} 23 | - {os: windows-latest, r: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | 26 | env: 27 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 28 | R_KEEP_PKG_SOURCE: yes 29 | 30 | steps: 31 | - uses: actions/checkout@v6 32 | 33 | - uses: r-lib/actions/setup-pandoc@v2 34 | 35 | - uses: r-lib/actions/setup-r@v2 36 | with: 37 | r-version: ${{ matrix.config.r }} 38 | http-user-agent: ${{ matrix.config.http-user-agent }} 39 | use-public-rspm: true 40 | 41 | - uses: r-lib/actions/setup-r-dependencies@v2 42 | with: 43 | extra-packages: any::rcmdcheck 44 | needs: check 45 | 46 | - uses: r-lib/actions/check-r-package@v2 47 | with: 48 | upload-snapshots: true 49 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' 50 | -------------------------------------------------------------------------------- /R/zotero_references.R: -------------------------------------------------------------------------------- 1 | #' @title References for zotero 2 | #' @description Given a vector of identifiers, extract data for use in Zotero 3 | #' @param identifiers a character vector of identifiers 4 | #' @return a list with results 5 | #' @details See https://github.com/giocomai/zoteroR for working with Zotero from R 6 | #' @examples 7 | #' \dontrun{ 8 | #' if(interactive()){ 9 | #' ids <- c("10.1038/nrn3241", "CorpusID:37220927") 10 | #' zotero_references(ids) 11 | #' } 12 | #' } 13 | #' @seealso 14 | #' \code{\link[humaniformat]{parse_names}} 15 | #' @export 16 | #' @importFrom dplyr tibble as_tibble mutate select `%>%` 17 | #' @importFrom humaniformat parse_names 18 | #' @importFrom rlang .data 19 | #' @importFrom purrr possibly map 20 | zotero_references <- function(identifiers) { 21 | 22 | zotero <- function(identifier) { 23 | 24 | p1 <- S2_paper(identifier) 25 | 26 | Sys.sleep(S2_ratelimit()) 27 | 28 | journalArticle <- 29 | with(p1, dplyr::tibble( 30 | title = title, 31 | DOI = doi, 32 | URL = url, 33 | abstractNote = abstract, 34 | publicationTitle = venue, 35 | date = year 36 | )) 37 | 38 | authors <- p1$authors$name 39 | 40 | creators <- 41 | humaniformat::parse_names(authors) %>% 42 | dplyr::as_tibble() %>% 43 | dplyr::mutate(creatorType = "author") %>% 44 | dplyr::rename( 45 | firstName = .data$first_name, 46 | lastName = .data$last_name 47 | ) %>% 48 | dplyr::select( 49 | "creatorType", 50 | "firstName", 51 | "lastName" 52 | ) 53 | 54 | list( 55 | S2_paper = p1$paperId, 56 | journalArticle = journalArticle, 57 | creators = creators 58 | ) 59 | 60 | } 61 | 62 | z <- purrr::possibly(zotero, NULL) 63 | 64 | identifiers %>% purrr::map(z) 65 | } 66 | 67 | -------------------------------------------------------------------------------- /data-raw/author_search.R: -------------------------------------------------------------------------------- 1 | library(httr) 2 | library(rvest) 3 | 4 | search1 <- function(author) 5 | GET(sprintf("https://www.semanticscholar.org/search?q=%s&sort=relevance", URLencode(author))) 6 | 7 | search2 <- function(author) 8 | POST("https://www.semanticscholar.org/api/1/search", 9 | body = list(queryString = author), 10 | content_type("application/json")) 11 | 12 | 13 | 14 | # markus@sphere:~/repos/semcor$ time cat s2-corpus-000 | jq -r '.authors[] | ({author: .name, id: .ids[]}) | [.author, .id] | @csv' > authors-000.csv 15 | # 16 | # real 0m30,024s 17 | # user 0m29,477s 18 | # sys 0m2,822s 19 | 20 | 21 | #remotes::install_github("cwida/duckdb/tools/rpkg", build = FALSE) 22 | library(DBI) 23 | library(duckdb) 24 | library(dplyr) 25 | library(arrow) 26 | 27 | authors <- 28 | arrow::read_csv_arrow("~/repos/semcor/authors-000.csv", 29 | col_names = c("author_name", "author_id")) 30 | 31 | arrow::write_parquet(authors, "~/repos/semcor/authors.parquet") 32 | 33 | con <- dbConnect(duckdb::duckdb(), dbdir = ":memory:", read_only = FALSE) 34 | 35 | if (dbExistsTable(con, "authors")) dbRemoveTable(con, "authors") 36 | dbWriteTable(con, "authors", as.data.frame(authors)) 37 | 38 | dbSendStatement(con, "PRAGMA threads=10;") 39 | dbGetQuery(con, "SELECT count(*) from authors") 40 | 41 | sql <- "CREATE VIEW authorsp AS SELECT author_name, author_id FROM 42 | parquet_scan('/home/markus/repos/semcor/authors.parquet');" 43 | 44 | dbSendQuery(con, sql) 45 | 46 | # row count 47 | con %>% tbl("authorsp") %>% count() 48 | 49 | tictoc::tic() 50 | dbGetQuery(con, "SELECT * FROM authors where author_name like 'Gerald Q. Ma%'") 51 | tictoc::toc() 52 | 53 | # slightly faster against parquet file 54 | tictoc::tic() 55 | dbGetQuery(con, "SELECT * FROM authorsp where author_name like 'Gerald Q. Ma%'") 56 | tictoc::toc() 57 | 58 | # same when index for author_name 59 | dbExecute(con, "CREATE INDEX author_idx ON authors (author_name);") 60 | 61 | #dbExecute(con, "EXPORT DATABASE '/home/markus/repos/semcor/' (FORMAT PARQUET)") 62 | 63 | dbDisconnect(con, shutdown = TRUE) 64 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "man/figures/README-", 12 | out.width = "100%" 13 | ) 14 | ``` 15 | 16 | # semanticscholar 17 | 18 | 19 | [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental) 20 | [![R-CMD-check](https://github.com/KTH-Library/semanticscholar/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/KTH-Library/semanticscholar/actions/workflows/R-CMD-check.yaml) 21 | 22 | 23 | The goal of `semanticscholar` is to offer data access to data from Semantic Scholar through their lightweight API which can provide data on publications and authors. Semantic Scholar is a free, non-profit academic search and discovery engine whose mission is to empower researchers. 24 | 25 | ## Installation 26 | 27 | You can install the current version of `semanticscholar` from [GitHub](https://github.com/kth-library/semanticscholar) with: 28 | 29 | ``` r 30 | #install.packages("devtools") 31 | devtools::install_github("kth-library/semanticscholar", dependencies = TRUE) 32 | ``` 33 | 34 | ## Example 35 | 36 | This is a basic example which shows you how to get information for papers and authors: 37 | 38 | ```{r example} 39 | 40 | library(semanticscholar) 41 | library(dplyr) 42 | suppressPackageStartupMessages(library(purrr)) 43 | library(knitr) 44 | 45 | # get a paper using an identifier 46 | paper <- S2_paper2("arXiv:1705.10311", details = "authors") 47 | 48 | # authors on that paper 49 | authors <- paper$data 50 | 51 | # for one of the authors 52 | author_ids <- authors$authorId 53 | Sys.sleep(1) 54 | author <- S2_author2(author_ids[1]) 55 | 56 | # get just paper count, citation count and hIndex for a specific author 57 | Sys.sleep(1) 58 | countz <- S2_author2(author_ids[1], fields = "url,paperCount,citationCount,hIndex") 59 | countz |> dplyr::as_tibble() 60 | 61 | # for a specific paper, get the TLDR; 62 | 63 | Sys.sleep(1) 64 | S2_paper2(identifier = "649def34f8be52c8b66281af98ae884c09aef38b", fields="tldr")$tldr$text 65 | 66 | ``` 67 | 68 | ## Rate limits and endpoints 69 | 70 | By default the rate limit allows 100 request per 5 minute period. This allows for making new requests every 3-4 seconds. 71 | 72 | By requesting an API key from Semantic Scholar, this rate can be faster, such as 100 requests per second. If you want to use an API key provided by Semantic Scholar, then edit the `~/.Renviron` file to add the key as a value for an environment variable `SEMANTICSCHOLAR_API`. This R package will then use API endpoints which are faster, with higher rate limits than the regular API endpoints. 73 | 74 | The rate limit and API base URL endpoint can be verified: 75 | 76 | ```{r ratelimit} 77 | S2_api() 78 | S2_ratelimit() 79 | ``` 80 | 81 | ## Data source attribution 82 | 83 | When data from `semanticscholar` is displayed publicly, this attribution also needs to be displayed: 84 | 85 | `r S2_attribution()` 86 | 87 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $(".examples, div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent; 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Authors • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
    62 |
    63 | 102 | 103 | 104 | 105 |
    106 | 107 |
    108 |
    109 | 112 | 113 |
      114 |
    • 115 |

      Markus Skyttner. Maintainer, author. 116 |

      117 |
    • 118 |
    119 | 120 |
    121 | 122 |
    123 | 124 | 125 | 126 |
    127 | 130 | 131 |
    132 |

    Site built with pkgdown 1.6.1.

    133 |
    134 | 135 |
    136 |
    137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /docs/LICENSE-text.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | License • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
    62 |
    63 | 102 | 103 | 104 | 105 |
    106 | 107 |
    108 |
    109 | 112 | 113 |
    YEAR: 2020
    114 | COPYRIGHT HOLDER: Markus Skyttner
    115 | 
    116 | 117 |
    118 | 119 | 124 | 125 |
    126 | 127 | 128 | 129 |
    130 | 133 | 134 |
    135 |

    Site built with pkgdown 1.6.1.

    136 |
    137 | 138 |
    139 |
    140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Page not found (404) • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
    62 |
    63 | 102 | 103 | 104 | 105 |
    106 | 107 |
    108 |
    109 | 112 | 113 | Content not found. Please use links in the navbar. 114 | 115 |
    116 | 117 | 122 | 123 |
    124 | 125 | 126 | 127 |
    128 | 131 | 132 |
    133 |

    Site built with pkgdown 1.6.1.

    134 |
    135 | 136 |
    137 |
    138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | (function() { 6 | 'use strict'; 7 | 8 | window.Toc = { 9 | helpers: { 10 | // return all matching elements in the set, or their descendants 11 | findOrFilter: function($el, selector) { 12 | // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ 13 | // http://stackoverflow.com/a/12731439/358804 14 | var $descendants = $el.find(selector); 15 | return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); 16 | }, 17 | 18 | generateUniqueIdBase: function(el) { 19 | var text = $(el).text(); 20 | var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); 21 | return anchor || el.tagName.toLowerCase(); 22 | }, 23 | 24 | generateUniqueId: function(el) { 25 | var anchorBase = this.generateUniqueIdBase(el); 26 | for (var i = 0; ; i++) { 27 | var anchor = anchorBase; 28 | if (i > 0) { 29 | // add suffix 30 | anchor += '-' + i; 31 | } 32 | // check if ID already exists 33 | if (!document.getElementById(anchor)) { 34 | return anchor; 35 | } 36 | } 37 | }, 38 | 39 | generateAnchor: function(el) { 40 | if (el.id) { 41 | return el.id; 42 | } else { 43 | var anchor = this.generateUniqueId(el); 44 | el.id = anchor; 45 | return anchor; 46 | } 47 | }, 48 | 49 | createNavList: function() { 50 | return $(''); 51 | }, 52 | 53 | createChildNavList: function($parent) { 54 | var $childList = this.createNavList(); 55 | $parent.append($childList); 56 | return $childList; 57 | }, 58 | 59 | generateNavEl: function(anchor, text) { 60 | var $a = $(''); 61 | $a.attr('href', '#' + anchor); 62 | $a.text(text); 63 | var $li = $('
  • '); 64 | $li.append($a); 65 | return $li; 66 | }, 67 | 68 | generateNavItem: function(headingEl) { 69 | var anchor = this.generateAnchor(headingEl); 70 | var $heading = $(headingEl); 71 | var text = $heading.data('toc-text') || $heading.text(); 72 | return this.generateNavEl(anchor, text); 73 | }, 74 | 75 | // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). 76 | getTopLevel: function($scope) { 77 | for (var i = 1; i <= 6; i++) { 78 | var $headings = this.findOrFilter($scope, 'h' + i); 79 | if ($headings.length > 1) { 80 | return i; 81 | } 82 | } 83 | 84 | return 1; 85 | }, 86 | 87 | // returns the elements for the top level, and the next below it 88 | getHeadings: function($scope, topLevel) { 89 | var topSelector = 'h' + topLevel; 90 | 91 | var secondaryLevel = topLevel + 1; 92 | var secondarySelector = 'h' + secondaryLevel; 93 | 94 | return this.findOrFilter($scope, topSelector + ',' + secondarySelector); 95 | }, 96 | 97 | getNavLevel: function(el) { 98 | return parseInt(el.tagName.charAt(1), 10); 99 | }, 100 | 101 | populateNav: function($topContext, topLevel, $headings) { 102 | var $context = $topContext; 103 | var $prevNav; 104 | 105 | var helpers = this; 106 | $headings.each(function(i, el) { 107 | var $newNav = helpers.generateNavItem(el); 108 | var navLevel = helpers.getNavLevel(el); 109 | 110 | // determine the proper $context 111 | if (navLevel === topLevel) { 112 | // use top level 113 | $context = $topContext; 114 | } else if ($prevNav && $context === $topContext) { 115 | // create a new level of the tree and switch to it 116 | $context = helpers.createChildNavList($prevNav); 117 | } // else use the current $context 118 | 119 | $context.append($newNav); 120 | 121 | $prevNav = $newNav; 122 | }); 123 | }, 124 | 125 | parseOps: function(arg) { 126 | var opts; 127 | if (arg.jquery) { 128 | opts = { 129 | $nav: arg 130 | }; 131 | } else { 132 | opts = arg; 133 | } 134 | opts.$scope = opts.$scope || $(document.body); 135 | return opts; 136 | } 137 | }, 138 | 139 | // accepts a jQuery object, or an options object 140 | init: function(opts) { 141 | opts = this.helpers.parseOps(opts); 142 | 143 | // ensure that the data attribute is in place for styling 144 | opts.$nav.attr('data-toggle', 'toc'); 145 | 146 | var $topContext = this.helpers.createChildNavList(opts.$nav); 147 | var topLevel = this.helpers.getTopLevel(opts.$scope); 148 | var $headings = this.helpers.getHeadings(opts.$scope, topLevel); 149 | this.helpers.populateNav($topContext, topLevel, $headings); 150 | } 151 | }; 152 | 153 | $(function() { 154 | $('nav[data-toggle="toc"]').each(function(i, el) { 155 | var $nav = $(el); 156 | Toc.init($nav); 157 | }); 158 | }); 159 | })(); 160 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # semanticscholar 5 | 6 | 7 | 8 | [![Lifecycle: 9 | experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental) 10 | [![R-CMD-check](https://github.com/KTH-Library/semanticscholar/workflows/R-CMD-check/badge.svg)](https://github.com/KTH-Library/semanticscholar/actions) 11 | 12 | 13 | The goal of `semanticscholar` is to offer data access to data from 14 | Semantic Scholar through their lightweight API which can provide data on 15 | publications and authors. Semantic Scholar is a free, non-profit 16 | academic search and discovery engine whose mission is to empower 17 | researchers. 18 | 19 | ## Installation 20 | 21 | You can install the current version of `semanticscholar` from 22 | [GitHub](https://github.com/kth-library/semanticscholar) with: 23 | 24 | ``` r 25 | #install.packages("devtools") 26 | devtools::install_github("kth-library/semanticscholar", dependencies = TRUE) 27 | ``` 28 | 29 | ## Example 30 | 31 | This is a basic example which shows you how to get information for 32 | papers and authors: 33 | 34 | ``` r 35 | library(semanticscholar) 36 | library(dplyr) 37 | #> 38 | #> Attaching package: 'dplyr' 39 | #> The following objects are masked from 'package:stats': 40 | #> 41 | #> filter, lag 42 | #> The following objects are masked from 'package:base': 43 | #> 44 | #> intersect, setdiff, setequal, union 45 | suppressPackageStartupMessages(library(purrr)) 46 | library(knitr) 47 | 48 | # get a paper using an identifier 49 | paper <- S2_paper("arXiv:1705.10311", include_unknown_refs = TRUE) 50 | 51 | # authors on that paper 52 | authors <- paper$authors 53 | 54 | # for one of the authors 55 | author_ids <- authors$authorId 56 | author <- S2_author(author_ids[1]) 57 | 58 | # get just paper count, citation count and hIndex for a specific author 59 | countz <- S2_author2(author_ids[1], fields = "url,paperCount,citationCount,hIndex") 60 | countz %>% dplyr::as_tibble() 61 | #> # A tibble: 1 × 5 62 | #> authorId url paperCount citationCount hIndex 63 | #> 64 | #> 1 3324024 https://www.semanticscholar.org/auth… 31 1127 12 65 | 66 | # for a specific paper, get the TLDR; 67 | 68 | S2_paper2(identifier = "649def34f8be52c8b66281af98ae884c09aef38b", fields="tldr")$tldr$text 69 | #> [1] "This paper reduces literature graph construction into familiar NLP tasks, point out research challenges due to differences from standard formulations of these tasks, and report empirical results for each task." 70 | 71 | # list some of the papers 72 | papers <- 73 | author$papers %>% 74 | select(title, year) 75 | 76 | papers %>% head(5) %>% knitr::kable() 77 | ``` 78 | 79 | | title | year | 80 | |:---------------------------------------------------------------------------------------------|-----:| 81 | | Artificial Intelligence Distinguishes COVID-19 from Community Acquired Pneumonia on Chest CT | 2020 | 82 | | Optimal Multiple Surface Segmentation With Shape and Context Priors | 2013 | 83 | | Optimal Co-Segmentation of Tumor in PET-CT Images With Context Information | 2013 | 84 | | Error-Tolerant Scribbles Based Interactive Image Segmentation | 2014 | 85 | | Automated anatomical labeling of coronary arteries via bidirectional tree LSTMs | 2018 | 86 | 87 | ``` r 88 | # get data from several identifiers for importing into Zotero 89 | ids <- c("10.1038/nrn3241", "CorpusID:37220927") 90 | my_refs <- zotero_references(ids) 91 | 92 | # this data can now be imported via the Zetero API using https://github.com/giocomai/zoteroR 93 | # showing data form the first record 94 | my_refs[[1]]$journalArticle %>% glimpse() 95 | #> Rows: 1 96 | #> Columns: 6 97 | #> $ title "The origin of extracellular fields and currents — EE… 98 | #> $ DOI "10.1038/nrn3241" 99 | #> $ URL "https://www.semanticscholar.org/paper/da82f8e6ff0094… 100 | #> $ abstractNote "Neuronal activity in the brain gives rise to transme… 101 | #> $ publicationTitle "Nature Reviews Neuroscience" 102 | #> $ date 2012 103 | my_refs[[2]]$creators %>% knitr::kable() 104 | ``` 105 | 106 | | creatorType | firstName | lastName | 107 | |:------------|:----------|:------------| 108 | | author | G. | Kawchuk | 109 | | author | N. | Prasad | 110 | | author | R. | Chamberlain | 111 | | author | A. | Klymkiv | 112 | | author | L. | Peter | 113 | 114 | ## Rate limits and endpoints 115 | 116 | By default the rate limit allows 100 request per 5 minute period. This 117 | allows for making new requests every 3-4 seconds. 118 | 119 | By requesting an API key from Semantic Scholar, this rate can be faster, 120 | such as 100 requests per second. If you want to use an API key provided 121 | by Semantic Scholar, then edit the `~/.Renviron` file to add the key as 122 | a value for an environment variable `SEMANTICSCHOLAR_API`. This R 123 | package will then use API endpoints which are faster, with higher rate 124 | limits than the regular API endpoints. 125 | 126 | The rate limit and API base URL endpoint can be verified: 127 | 128 | ``` r 129 | S2_api() 130 | #> [1] "https://partner.semanticscholar.org/" 131 | S2_ratelimit() 132 | #> [1] 0.01010101 133 | ``` 134 | 135 | ## Data source attribution 136 | 137 | When data from `semanticscholar` is displayed publicly, this attribution 138 | also needs to be displayed: 139 | 140 | Data source: Semantic Scholar API 141 | 142 | -------------------------------------------------------------------------------- /docs/reference/S2_fields.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Valid fields available for use in API calls — S2_fields • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 103 | 104 | 105 | 106 |
    107 | 108 |
    109 |
    110 | 115 | 116 |
    117 |

    Valid fields available for use in API calls

    118 |
    119 | 120 |
    S2_fields()
    121 | 122 | 123 | 124 |
    125 | 130 |
    131 | 132 | 133 |
    134 | 137 | 138 |
    139 |

    Site built with pkgdown 1.6.1.

    140 |
    141 | 142 |
    143 |
    144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /docs/reference/semanticscholar-package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Data from Semantic Scholar for use in R — semanticscholar-package • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
    64 |
    65 | 104 | 105 | 106 | 107 |
    108 | 109 |
    110 |
    111 | 116 | 117 |
    118 |

    This package provides on-demand data access to Semantic Scholar 119 | through a lightweight API for author and publication data.

    120 |
    121 | 122 | 123 | 124 | 125 |
    126 | 131 |
    132 | 133 | 134 |
    135 | 138 | 139 |
    140 |

    Site built with pkgdown 1.6.1.

    141 |
    142 | 143 |
    144 |
    145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/reference/S2_api.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Endpoint used for requests to Semantic Scholar API — S2_api • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
    64 |
    65 | 104 | 105 | 106 | 107 |
    108 | 109 |
    110 |
    111 | 116 | 117 |
    118 |

    When environment variable SEMANTICSCHOLAR_API is set to a valid API key this 119 | value differs as endpoints allowing higher rate limits are being used.

    120 |
    121 | 122 |
    S2_api()
    123 | 124 | 125 | 126 |
    127 | 132 |
    133 | 134 | 135 |
    136 | 139 | 140 |
    141 |

    Site built with pkgdown 1.6.1.

    142 |
    143 | 144 |
    145 |
    146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/reference/S2_ratelimit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Rate limit for API calls — S2_ratelimit • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 103 | 104 | 105 | 106 |
    107 | 108 |
    109 |
    110 | 115 | 116 |
    117 |

    The minimum interval in seconds between requests to the API.

    118 |
    119 | 120 |
    S2_ratelimit()
    121 | 122 | 123 |

    Details

    124 | 125 |

    When environment variable SEMANTICSCHOLAR_API is set to a valid API key this 126 | value can be approx 0.01 (for 100 requests per second) but if no API key is 127 | used, the default value will be around 3.5 (allowing a maximum of 100 requests per 5 minutes)

    128 | 129 |
    130 | 135 |
    136 | 137 | 138 |
    139 | 142 | 143 |
    144 |

    Site built with pkgdown 1.6.1.

    145 |
    146 | 147 |
    148 |
    149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /docs/LICENSE.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | MIT License • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
    62 |
    63 | 102 | 103 | 104 | 105 |
    106 | 107 |
    108 |
    109 | 112 | 113 |
    114 | 115 |

    Copyright (c) 2020 Markus Skyttner

    116 |

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    117 |

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    118 |

    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    119 |
    120 | 121 |
    122 | 123 | 128 | 129 |
    130 | 131 | 132 | 133 |
    134 | 137 | 138 |
    139 |

    Site built with pkgdown 1.6.1.

    140 |
    141 | 142 |
    143 |
    144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /docs/reference/S2_attribution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Attribution — S2_attribution • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 103 | 104 | 105 | 106 |
    107 | 108 |
    109 |
    110 | 115 | 116 |
    117 |

    Use this attribution whenever data from the API is publicly displayed

    118 |
    119 | 120 |
    S2_attribution()
    121 | 122 | 123 |

    Details

    124 | 125 |

    Semantic Scholar provides a RESTful API for convenient linking 126 | to Semantic Scholar pages and pulling information about individual records 127 | on demand. When publicly displaying data from this API, 128 | please incorporate the Semantic Scholar name and logo and point back to 129 | Semantic Scholar at https://www.semanticscholar.org/ with 130 | a utm_source=api UTM parameter.

    131 | 132 |
    133 | 138 |
    139 | 140 | 141 |
    142 | 145 | 146 |
    147 |

    Site built with pkgdown 1.6.1.

    148 |
    149 | 150 |
    151 |
    152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /tests/testthat/test-S2_v2.R: -------------------------------------------------------------------------------- 1 | test_that("Paper search with paging works", { 2 | skip_on_ci() 3 | res <- S2_search_papers("covid vaccination", offset = 100, limit = 3) 4 | is_valid <- nrow(res$data) == 3 && (res$offset == 100) && (res$total > 6e5) 5 | expect_true(is_valid) 6 | }) 7 | 8 | test_that("Paper search includes a set of fields", { 9 | skip_on_ci() 10 | res <- S2_search_papers("covid", fields = "url,abstract,authors") 11 | n_authors <- vapply(res$data$authors, nrow, integer(1)) 12 | has_fields <- all(c("url", "abstract", "authors") %in% names(res$data)) 13 | is_valid <- all(n_authors > 0) && has_fields 14 | expect_true(is_valid) 15 | }) 16 | 17 | test_that("Paper search for garbage term is empty", { 18 | skip_on_ci() 19 | res <- S2_search_papers("totalGarbageNonsense") 20 | is_valid <- (res$total == 0) && (res$offset == 0) && (length(res$data) == 0) 21 | expect_true(is_valid) 22 | }) 23 | 24 | test_that("Paper with authors, year and url", { 25 | skip_on_ci() 26 | res <- S2_paper2("649def34f8be52c8b66281af98ae884c09aef38b", fields = "url,year,authors") 27 | is_valid <- (res$url == "https://www.semanticscholar.org/paper/649def34f8be52c8b66281af98ae884c09aef38b") && 28 | (res$year == 2018) && (nrow(res$authors) > 20) 29 | expect_true(is_valid) 30 | }) 31 | 32 | test_that("Paper with citations with authors", { 33 | skip_on_ci() 34 | # TODO: double check this test 35 | # https://api.semanticscholar.org/graph/v1/paper/649def34f8be52c8b66281af98ae884c09aef38b/citations?fields=authors&offset=1500&limit=500 36 | # Returns with offset=1500, and data is a list of the last 100 citations. 37 | # Each citation has a citingPaper which contains its paperId plus a list of authors 38 | # The authors under each citingPaper has their authorId and name. 39 | res <- S2_paper2("649def34f8be52c8b66281af98ae884c09aef38b", fields = "citations.authors") 40 | is_valid <- all(vapply(res$citations$authors, nrow, integer(1)) >= 0) 41 | expect_true(is_valid) 42 | }) 43 | 44 | test_that("Paper with list of twentythree authors", { 45 | skip_on_ci() 46 | res <- S2_paper2("649def34f8be52c8b66281af98ae884c09aef38b", details = "authors", limit = 50) 47 | is_valid <- nrow(res$data) >= 23 48 | expect_true(is_valid) 49 | }) 50 | 51 | test_that("Paper with authors and their affiliations and papers", { 52 | skip_on_ci() 53 | 54 | res <- S2_paper2("649def34f8be52c8b66281af98ae884c09aef38b", 55 | details = "authors", fields = "affiliations,papers.paperId", limit = 20) 56 | 57 | is_valid <- length(res$data$affiliations) == 20 58 | expect_true(is_valid) 59 | }) 60 | 61 | test_that("Paper with authors and their url, years and authors", { 62 | skip_on_ci() 63 | 64 | res <- S2_paper2("649def34f8be52c8b66281af98ae884c09aef38b", 65 | details = "authors", fields = "url,papers.year,papers.authors", offset = 2) 66 | 67 | is_valid <- length(res$data$url) == 10 && all(nchar(res$data$url) > 10) 68 | expect_true(is_valid) 69 | }) 70 | 71 | 72 | test_that("Paper with 100 citations works", { 73 | skip_on_ci() 74 | 75 | res <- S2_paper2("649def34f8be52c8b66281af98ae884c09aef38b", 76 | details = "citations", limit = 100) 77 | 78 | is_valid <- length(res$data$citingPaper$paperId) == 100 && 79 | all(nchar(res$data$citingPaper$paperId) > 10) 80 | 81 | expect_true(is_valid) 82 | }) 83 | 84 | test_that("Paper with 100+ citations works", { 85 | skip_on_ci() 86 | 87 | fields <- "contexts,intents,isInfluential" 88 | validate_fields(fields, "paper_citations") 89 | 90 | res <- 91 | S2_paper2( 92 | identifier = "649def34f8be52c8b66281af98ae884c09aef38b", 93 | details = "citations", 94 | fields = fields, 95 | offset = 20, 96 | limit = 10 97 | ) 98 | 99 | is_valid <- (res$offset == 20) && !is.null(res$data) 100 | 101 | expect_true(is_valid) 102 | }) 103 | 104 | test_that("Paper with references and paging works", { 105 | skip_on_ci() 106 | 107 | res <- 108 | S2_paper2( 109 | identifier = "649def34f8be52c8b66281af98ae884c09aef38b", 110 | details = "references", 111 | fields = "contexts,intents,isInfluential,abstract", 112 | offset = 20, 113 | limit = 10 114 | ) 115 | 116 | is_valid <- (res$offset == 20) && !is.null(res$data) 117 | 118 | expect_true(is_valid) 119 | }) 120 | 121 | test_that("Author with fields for papers works", { 122 | skip_on_ci() 123 | 124 | res <- S2_author2(1741101, 125 | fields = "papers", 126 | offset = 20, limit = 10) 127 | 128 | is_valid <- all(c("paperId", "title") %in% names(res$papers)) 129 | expect_true(is_valid) 130 | 131 | }) 132 | 133 | test_that("Author with fields for paper abstracts and authors works", { 134 | skip_on_ci() 135 | 136 | res <- S2_author2(1741101, 137 | fields = "url,papers.abstract,papers.authors", 138 | offset = 20, limit = 10) 139 | 140 | # TODO: check the paging! why does not offset and limit appear in the result? 141 | 142 | is_valid <- all(c("paperId", "abstract", "authors") %in% names(res$papers)) 143 | expect_true(is_valid) 144 | 145 | }) 146 | 147 | test_that("Author with various paper fields and paging works", { 148 | skip_on_ci() 149 | 150 | res <- S2_author2(1741101, details = "papers", 151 | fields = "url,year,authors", limit = 2) 152 | 153 | is_valid <- all(c("paperId", "url", "year") %in% names(res$data)) && (nrow(res$data) == 2) 154 | expect_true(is_valid) 155 | 156 | }) 157 | 158 | test_that("Author with various paper fields incl citations.authors and paging works", { 159 | skip_on_ci() 160 | 161 | res <- S2_author2(1741101, details = "papers", fields = "citations.authors", 162 | offset = 250) 163 | 164 | is_valid <- all(c("paperId", "citations") %in% names(res$data)) && (nrow(res$data) >= 4) 165 | expect_true(is_valid) 166 | 167 | }) 168 | 169 | 170 | test_that("Author with fields for paperCount, citationCount, hIndex works", { 171 | skip_on_ci() 172 | 173 | res <- S2_author2(1741101, 174 | fields = "url,paperCount,citationCount,hIndex", 175 | #fields = "url,paperCount", 176 | offset = 20, limit = 10) 177 | 178 | is_valid <- all(c("authorId", "url", "paperCount", "citationCount", "hIndex") %in% names(res)) 179 | expect_true(is_valid) 180 | 181 | }) 182 | 183 | test_that("Paper TLDR can be returned", { 184 | skip_on_ci() 185 | tldr <- S2_paper2(identifier = "649def34f8be52c8b66281af98ae884c09aef38b", fields="tldr")$tldr$text 186 | is_valid <- nchar(tldr) > 20 187 | expect_true(is_valid) 188 | }) 189 | 190 | -------------------------------------------------------------------------------- /docs/reference/S2_author.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Retrieve author information — S2_author • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
    64 |
    65 | 104 | 105 | 106 | 107 |
    108 | 109 |
    110 |
    111 | 116 | 117 |
    118 |

    This function retrieves Semantic Scholar data for 119 | an author given the S2Author identifier

    120 |
    121 | 122 |
    S2_author(S2AuthorId)
    123 | 124 |

    Arguments

    125 | 126 | 127 | 128 | 129 | 130 | 131 |
    S2AuthorId

    string with author identifier

    132 | 133 |

    Value

    134 | 135 |

    list representing author object

    136 |

    Details

    137 | 138 |

    Example of Accessible Paper Identifiers:

      139 |
    • S2 Author ID : 1741101

    • 140 |
    141 | 142 | 143 |

    Examples

    144 |
    if (FALSE) { 145 | S2_author(1741101) 146 | } 147 |
    148 |
    149 | 154 |
    155 | 156 | 157 |
    158 | 161 | 162 |
    163 |

    Site built with pkgdown 1.6.1.

    164 |
    165 | 166 |
    167 |
    168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /docs/reference/S2_search_papers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | This function retrieves Semantic Scholar data for 10 | a keyword search — S2_search_papers • semanticscholar 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
    66 |
    67 | 106 | 107 | 108 | 109 |
    110 | 111 |
    112 |
    113 | 119 | 120 |
    121 |

    This function retrieves Semantic Scholar data for 122 | a keyword search

    123 |
    124 | 125 |
    S2_search_papers(keyword, offset = 0, limit = 10, fields = NULL)
    126 | 127 |

    Arguments

    128 | 129 | 130 | 131 | 132 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 |
    keyword

    string with keywords to search for, supports AND and OR and 133 | inclusion and exclusion of terms, for example "+Epidemic +Modeling +Canada -COVID"

    offset

    integer paging offset

    limit

    integer paging length

    fields

    extra fields to include, for example "title,authors"

    148 | 149 |

    Value

    150 | 151 |

    list representing paper objects

    152 | 153 |

    Examples

    154 |
    if (FALSE) { 155 | S2_search_papers(keyword = "literature graph") 156 | } 157 |
    158 |
    159 | 164 |
    165 | 166 | 167 |
    168 | 171 | 172 |
    173 |

    Site built with pkgdown 1.6.1.

    174 |
    175 | 176 |
    177 |
    178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /docs/reference/S2_paper.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Retrieve paper information — S2_paper • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
    64 |
    65 | 104 | 105 | 106 | 107 |
    108 | 109 |
    110 |
    111 | 116 | 117 |
    118 |

    This function retrieves Semantic Scholar data for a paper 119 | given its identifier

    120 |
    121 | 122 |
    S2_paper(identifier, include_unknown_refs = FALSE)
    123 | 124 |

    Arguments

    125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 |
    identifier

    string with identifier

    include_unknown_refs

    logical, Default: FALSE

    136 | 137 |

    Value

    138 | 139 |

    list representing S2 paper object

    140 |

    Details

    141 | 142 |

    Example of Accessible Paper Identifiers:

      143 |
    • S2 Paper ID : 0796f6cd7f0403a854d67d525e9b32af3b277331

    • 144 |
    • DOI : 10.1038/nrn3241

    • 145 |
    • ArXiv ID : arXiv:1705.10311

    • 146 |
    • MAG ID : MAG:112218234

    • 147 |
    • ACL ID : ACL:W12-3903

    • 148 |
    • PubMed ID : PMID:19872477

    • 149 |
    • Corpus ID : CorpusID:37220927

    • 150 |
    151 | 152 |

    S2 is an abbreviation for Semantic Scholar 153 | MAG is an abbreviation for Microsoft Academic Graph

    154 | 155 |

    Examples

    156 |
    if (FALSE) { 157 | S2_paper("fb5d1bb23724d9a5a5eae036a2e3cf291cac2c1b") 158 | } 159 |
    160 |
    161 | 166 |
    167 | 168 | 169 |
    170 | 173 | 174 |
    175 |

    Site built with pkgdown 1.6.1.

    176 |
    177 | 178 |
    179 |
    180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /docs/reference/zotero_references.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | References for zotero — zotero_references • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 103 | 104 | 105 | 106 |
    107 | 108 |
    109 |
    110 | 115 | 116 |
    117 |

    Given a vector of identifiers, extract data for use in Zotero

    118 |
    119 | 120 |
    zotero_references(identifiers)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 |
    identifiers

    a character vector of identifiers

    130 | 131 |

    Value

    132 | 133 |

    a list with results

    134 |

    Details

    135 | 136 |

    See https://github.com/giocomai/zoteroR for working with Zotero from R

    137 |

    See also

    138 | 139 | 140 | 141 |

    Examples

    142 |
    if (FALSE) { 143 | if(interactive()){ 144 | ids <- c("10.1038/nrn3241", "CorpusID:37220927") 145 | zotero_references(ids) 146 | } 147 | } 148 |
    149 |
    150 | 155 |
    156 | 157 | 158 |
    159 | 162 | 163 |
    164 |

    Site built with pkgdown 1.6.1.

    165 |
    166 | 167 |
    168 |
    169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /docs/reference/S2_paper2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | This function retrieves details about a paper's authors — S2_paper2 • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 |
    64 | 103 | 104 | 105 | 106 |
    107 | 108 |
    109 |
    110 | 115 | 116 |
    117 |

    This function retrieves details about a paper's authors

    118 |
    119 | 120 |
    S2_paper2(
    121 |   identifier,
    122 |   details = c("authors", "citations", "references"),
    123 |   offset = 0,
    124 |   limit = 10,
    125 |   fields = NULL
    126 | )
    127 | 128 |

    Arguments

    129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 |
    identifier

    string with keywords to search for

    details

    one of "authors", "citations" or "references"

    offset

    integer paging offset

    limit

    integer paging length

    fields

    extra fields to include, for example "title,authors"

    152 | 153 |

    Value

    154 | 155 |

    list representing paper objects

    156 | 157 |

    Examples

    158 |
    if (FALSE) { 159 | S2_paper2(identifier = "649def34f8be52c8b66281af98ae884c09aef38b") 160 | } 161 |
    162 |
    163 | 168 |
    169 | 170 | 171 |
    172 | 175 | 176 |
    177 |

    Site built with pkgdown 1.6.1.

    178 |
    179 | 180 |
    181 |
    182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /docs/reference/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Function reference • semanticscholar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
    62 |
    63 | 102 | 103 | 104 | 105 |
    106 | 107 |
    108 |
    109 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 138 | 139 | 140 | 141 | 144 | 145 | 146 | 147 | 150 | 151 | 152 | 153 | 156 | 158 | 159 | 160 | 163 | 164 | 165 | 166 | 169 | 170 | 171 | 172 | 175 | 176 | 177 | 178 | 181 | 182 | 183 | 184 | 187 | 189 | 190 | 191 | 194 | 195 | 196 | 197 | 200 | 201 | 202 | 203 |
    124 |

    All functions

    125 |

    126 |
    136 |

    S2_api()

    137 |

    Endpoint used for requests to Semantic Scholar API

    142 |

    S2_attribution()

    143 |

    Attribution

    148 |

    S2_author()

    149 |

    Retrieve author information

    154 |

    S2_author2()

    155 |

    This function retrieves Semantic Scholar data for 157 | an author given the S2Author identifier

    161 |

    S2_fields()

    162 |

    Valid fields available for use in API calls

    167 |

    S2_paper()

    168 |

    Retrieve paper information

    173 |

    S2_paper2()

    174 |

    This function retrieves details about a paper's authors

    179 |

    S2_ratelimit()

    180 |

    Rate limit for API calls

    185 |

    S2_search_papers()

    186 |

    This function retrieves Semantic Scholar data for 188 | a keyword search

    192 |

    semanticscholar-package

    193 |

    Data from Semantic Scholar for use in R

    198 |

    zotero_references()

    199 |

    References for zotero

    204 |
    205 | 206 | 211 |
    212 | 213 | 214 |
    215 | 218 | 219 |
    220 |

    Site built with pkgdown 1.6.1.

    221 |
    222 | 223 |
    224 |
    225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer */ 2 | 3 | /** 4 | * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ 5 | * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css 6 | * 7 | * .Site -> body > .container 8 | * .Site-content -> body > .container .row 9 | * .footer -> footer 10 | * 11 | * Key idea seems to be to ensure that .container and __all its parents__ 12 | * have height set to 100% 13 | * 14 | */ 15 | 16 | html, body { 17 | height: 100%; 18 | } 19 | 20 | body { 21 | position: relative; 22 | } 23 | 24 | body > .container { 25 | display: flex; 26 | height: 100%; 27 | flex-direction: column; 28 | } 29 | 30 | body > .container .row { 31 | flex: 1 0 auto; 32 | } 33 | 34 | footer { 35 | margin-top: 45px; 36 | padding: 35px 0 36px; 37 | border-top: 1px solid #e5e5e5; 38 | color: #666; 39 | display: flex; 40 | flex-shrink: 0; 41 | } 42 | footer p { 43 | margin-bottom: 0; 44 | } 45 | footer div { 46 | flex: 1; 47 | } 48 | footer .pkgdown { 49 | text-align: right; 50 | } 51 | footer p { 52 | margin-bottom: 0; 53 | } 54 | 55 | img.icon { 56 | float: right; 57 | } 58 | 59 | img { 60 | max-width: 100%; 61 | } 62 | 63 | /* Fix bug in bootstrap (only seen in firefox) */ 64 | summary { 65 | display: list-item; 66 | } 67 | 68 | /* Typographic tweaking ---------------------------------*/ 69 | 70 | .contents .page-header { 71 | margin-top: calc(-60px + 1em); 72 | } 73 | 74 | dd { 75 | margin-left: 3em; 76 | } 77 | 78 | /* Section anchors ---------------------------------*/ 79 | 80 | a.anchor { 81 | margin-left: -30px; 82 | display:inline-block; 83 | width: 30px; 84 | height: 30px; 85 | visibility: hidden; 86 | 87 | background-image: url(./link.svg); 88 | background-repeat: no-repeat; 89 | background-size: 20px 20px; 90 | background-position: center center; 91 | } 92 | 93 | .hasAnchor:hover a.anchor { 94 | visibility: visible; 95 | } 96 | 97 | @media (max-width: 767px) { 98 | .hasAnchor:hover a.anchor { 99 | visibility: hidden; 100 | } 101 | } 102 | 103 | 104 | /* Fixes for fixed navbar --------------------------*/ 105 | 106 | .contents h1, .contents h2, .contents h3, .contents h4 { 107 | padding-top: 60px; 108 | margin-top: -40px; 109 | } 110 | 111 | /* Navbar submenu --------------------------*/ 112 | 113 | .dropdown-submenu { 114 | position: relative; 115 | } 116 | 117 | .dropdown-submenu>.dropdown-menu { 118 | top: 0; 119 | left: 100%; 120 | margin-top: -6px; 121 | margin-left: -1px; 122 | border-radius: 0 6px 6px 6px; 123 | } 124 | 125 | .dropdown-submenu:hover>.dropdown-menu { 126 | display: block; 127 | } 128 | 129 | .dropdown-submenu>a:after { 130 | display: block; 131 | content: " "; 132 | float: right; 133 | width: 0; 134 | height: 0; 135 | border-color: transparent; 136 | border-style: solid; 137 | border-width: 5px 0 5px 5px; 138 | border-left-color: #cccccc; 139 | margin-top: 5px; 140 | margin-right: -10px; 141 | } 142 | 143 | .dropdown-submenu:hover>a:after { 144 | border-left-color: #ffffff; 145 | } 146 | 147 | .dropdown-submenu.pull-left { 148 | float: none; 149 | } 150 | 151 | .dropdown-submenu.pull-left>.dropdown-menu { 152 | left: -100%; 153 | margin-left: 10px; 154 | border-radius: 6px 0 6px 6px; 155 | } 156 | 157 | /* Sidebar --------------------------*/ 158 | 159 | #pkgdown-sidebar { 160 | margin-top: 30px; 161 | position: -webkit-sticky; 162 | position: sticky; 163 | top: 70px; 164 | } 165 | 166 | #pkgdown-sidebar h2 { 167 | font-size: 1.5em; 168 | margin-top: 1em; 169 | } 170 | 171 | #pkgdown-sidebar h2:first-child { 172 | margin-top: 0; 173 | } 174 | 175 | #pkgdown-sidebar .list-unstyled li { 176 | margin-bottom: 0.5em; 177 | } 178 | 179 | /* bootstrap-toc tweaks ------------------------------------------------------*/ 180 | 181 | /* All levels of nav */ 182 | 183 | nav[data-toggle='toc'] .nav > li > a { 184 | padding: 4px 20px 4px 6px; 185 | font-size: 1.5rem; 186 | font-weight: 400; 187 | color: inherit; 188 | } 189 | 190 | nav[data-toggle='toc'] .nav > li > a:hover, 191 | nav[data-toggle='toc'] .nav > li > a:focus { 192 | padding-left: 5px; 193 | color: inherit; 194 | border-left: 1px solid #878787; 195 | } 196 | 197 | nav[data-toggle='toc'] .nav > .active > a, 198 | nav[data-toggle='toc'] .nav > .active:hover > a, 199 | nav[data-toggle='toc'] .nav > .active:focus > a { 200 | padding-left: 5px; 201 | font-size: 1.5rem; 202 | font-weight: 400; 203 | color: inherit; 204 | border-left: 2px solid #878787; 205 | } 206 | 207 | /* Nav: second level (shown on .active) */ 208 | 209 | nav[data-toggle='toc'] .nav .nav { 210 | display: none; /* Hide by default, but at >768px, show it */ 211 | padding-bottom: 10px; 212 | } 213 | 214 | nav[data-toggle='toc'] .nav .nav > li > a { 215 | padding-left: 16px; 216 | font-size: 1.35rem; 217 | } 218 | 219 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 220 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 221 | padding-left: 15px; 222 | } 223 | 224 | nav[data-toggle='toc'] .nav .nav > .active > a, 225 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 226 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 227 | padding-left: 15px; 228 | font-weight: 500; 229 | font-size: 1.35rem; 230 | } 231 | 232 | /* orcid ------------------------------------------------------------------- */ 233 | 234 | .orcid { 235 | font-size: 16px; 236 | color: #A6CE39; 237 | /* margins are required by official ORCID trademark and display guidelines */ 238 | margin-left:4px; 239 | margin-right:4px; 240 | vertical-align: middle; 241 | } 242 | 243 | /* Reference index & topics ----------------------------------------------- */ 244 | 245 | .ref-index th {font-weight: normal;} 246 | 247 | .ref-index td {vertical-align: top; min-width: 100px} 248 | .ref-index .icon {width: 40px;} 249 | .ref-index .alias {width: 40%;} 250 | .ref-index-icons .alias {width: calc(40% - 40px);} 251 | .ref-index .title {width: 60%;} 252 | 253 | .ref-arguments th {text-align: right; padding-right: 10px;} 254 | .ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} 255 | .ref-arguments .name {width: 20%;} 256 | .ref-arguments .desc {width: 80%;} 257 | 258 | /* Nice scrolling for wide elements --------------------------------------- */ 259 | 260 | table { 261 | display: block; 262 | overflow: auto; 263 | } 264 | 265 | /* Syntax highlighting ---------------------------------------------------- */ 266 | 267 | pre { 268 | word-wrap: normal; 269 | word-break: normal; 270 | border: 1px solid #eee; 271 | } 272 | 273 | pre, code { 274 | background-color: #f8f8f8; 275 | color: #333; 276 | } 277 | 278 | pre code { 279 | overflow: auto; 280 | word-wrap: normal; 281 | white-space: pre; 282 | } 283 | 284 | pre .img { 285 | margin: 5px 0; 286 | } 287 | 288 | pre .img img { 289 | background-color: #fff; 290 | display: block; 291 | height: auto; 292 | } 293 | 294 | code a, pre a { 295 | color: #375f84; 296 | } 297 | 298 | a.sourceLine:hover { 299 | text-decoration: none; 300 | } 301 | 302 | .fl {color: #1514b5;} 303 | .fu {color: #000000;} /* function */ 304 | .ch,.st {color: #036a07;} /* string */ 305 | .kw {color: #264D66;} /* keyword */ 306 | .co {color: #888888;} /* comment */ 307 | 308 | .message { color: black; font-weight: bolder;} 309 | .error { color: orange; font-weight: bolder;} 310 | .warning { color: #6A0366; font-weight: bolder;} 311 | 312 | /* Clipboard --------------------------*/ 313 | 314 | .hasCopyButton { 315 | position: relative; 316 | } 317 | 318 | .btn-copy-ex { 319 | position: absolute; 320 | right: 0; 321 | top: 0; 322 | visibility: hidden; 323 | } 324 | 325 | .hasCopyButton:hover button.btn-copy-ex { 326 | visibility: visible; 327 | } 328 | 329 | /* headroom.js ------------------------ */ 330 | 331 | .headroom { 332 | will-change: transform; 333 | transition: transform 200ms linear; 334 | } 335 | .headroom--pinned { 336 | transform: translateY(0%); 337 | } 338 | .headroom--unpinned { 339 | transform: translateY(-100%); 340 | } 341 | 342 | /* mark.js ----------------------------*/ 343 | 344 | mark { 345 | background-color: rgba(255, 255, 51, 0.5); 346 | border-bottom: 2px solid rgba(255, 153, 51, 0.3); 347 | padding: 1px; 348 | } 349 | 350 | /* vertical spacing after htmlwidgets */ 351 | .html-widget { 352 | margin-bottom: 10px; 353 | } 354 | 355 | /* fontawesome ------------------------ */ 356 | 357 | .fab { 358 | font-family: "Font Awesome 5 Brands" !important; 359 | } 360 | 361 | /* don't display links in code chunks when printing */ 362 | /* source: https://stackoverflow.com/a/10781533 */ 363 | @media print { 364 | code a:link:after, code a:visited:after { 365 | content: ""; 366 | } 367 | } 368 | -------------------------------------------------------------------------------- /docs/reference/S2_author2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | This function retrieves Semantic Scholar data for 10 | an author given the S2Author identifier — S2_author2 • semanticscholar 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
    66 |
    67 | 106 | 107 | 108 | 109 |
    110 | 111 |
    112 |
    113 | 119 | 120 |
    121 |

    This function retrieves Semantic Scholar data for 122 | an author given the S2Author identifier

    123 |
    124 | 125 |
    S2_author2(
    126 |   S2AuthorId,
    127 |   details = c("papers"),
    128 |   offset = 0,
    129 |   limit = 10,
    130 |   fields = NULL
    131 | )
    132 | 133 |

    Arguments

    134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 |
    S2AuthorId

    string with author identifier

    details

    one of "authors", "citations" or "references"

    offset

    integer paging offset

    limit

    integer paging length

    fields

    extra fields to include, for example "title,authors"

    157 | 158 |

    Value

    159 | 160 |

    list representing author object

    161 |

    Details

    162 | 163 |

    Example of Accessible Paper Identifiers:

      164 |
    • S2 Author ID : 1681232

    • 165 |
    166 | 167 | 168 |

    Examples

    169 |
    if (FALSE) { 170 | S2_author(1681232) 171 | S2_author2(1681232, fields="affiliations,aliases,externalIds") 172 | S2_author2(1681232, fields="paperId,externalIds", details = "papers", offset=0, limit = 100) 173 | } 174 |
    175 |
    176 | 181 |
    182 | 183 | 184 |
    185 | 188 | 189 |
    190 |

    Site built with pkgdown 1.6.1.

    191 |
    192 | 193 |
    194 |
    195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /docs/docsearch.css: -------------------------------------------------------------------------------- 1 | /* Docsearch -------------------------------------------------------------- */ 2 | /* 3 | Source: https://github.com/algolia/docsearch/ 4 | License: MIT 5 | */ 6 | 7 | .algolia-autocomplete { 8 | display: block; 9 | -webkit-box-flex: 1; 10 | -ms-flex: 1; 11 | flex: 1 12 | } 13 | 14 | .algolia-autocomplete .ds-dropdown-menu { 15 | width: 100%; 16 | min-width: none; 17 | max-width: none; 18 | padding: .75rem 0; 19 | background-color: #fff; 20 | background-clip: padding-box; 21 | border: 1px solid rgba(0, 0, 0, .1); 22 | box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175); 23 | } 24 | 25 | @media (min-width:768px) { 26 | .algolia-autocomplete .ds-dropdown-menu { 27 | width: 175% 28 | } 29 | } 30 | 31 | .algolia-autocomplete .ds-dropdown-menu::before { 32 | display: none 33 | } 34 | 35 | .algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] { 36 | padding: 0; 37 | background-color: rgb(255,255,255); 38 | border: 0; 39 | max-height: 80vh; 40 | } 41 | 42 | .algolia-autocomplete .ds-dropdown-menu .ds-suggestions { 43 | margin-top: 0 44 | } 45 | 46 | .algolia-autocomplete .algolia-docsearch-suggestion { 47 | padding: 0; 48 | overflow: visible 49 | } 50 | 51 | .algolia-autocomplete .algolia-docsearch-suggestion--category-header { 52 | padding: .125rem 1rem; 53 | margin-top: 0; 54 | font-size: 1.3em; 55 | font-weight: 500; 56 | color: #00008B; 57 | border-bottom: 0 58 | } 59 | 60 | .algolia-autocomplete .algolia-docsearch-suggestion--wrapper { 61 | float: none; 62 | padding-top: 0 63 | } 64 | 65 | .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column { 66 | float: none; 67 | width: auto; 68 | padding: 0; 69 | text-align: left 70 | } 71 | 72 | .algolia-autocomplete .algolia-docsearch-suggestion--content { 73 | float: none; 74 | width: auto; 75 | padding: 0 76 | } 77 | 78 | .algolia-autocomplete .algolia-docsearch-suggestion--content::before { 79 | display: none 80 | } 81 | 82 | .algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header { 83 | padding-top: .75rem; 84 | margin-top: .75rem; 85 | border-top: 1px solid rgba(0, 0, 0, .1) 86 | } 87 | 88 | .algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column { 89 | display: block; 90 | padding: .1rem 1rem; 91 | margin-bottom: 0.1; 92 | font-size: 1.0em; 93 | font-weight: 400 94 | /* display: none */ 95 | } 96 | 97 | .algolia-autocomplete .algolia-docsearch-suggestion--title { 98 | display: block; 99 | padding: .25rem 1rem; 100 | margin-bottom: 0; 101 | font-size: 0.9em; 102 | font-weight: 400 103 | } 104 | 105 | .algolia-autocomplete .algolia-docsearch-suggestion--text { 106 | padding: 0 1rem .5rem; 107 | margin-top: -.25rem; 108 | font-size: 0.8em; 109 | font-weight: 400; 110 | line-height: 1.25 111 | } 112 | 113 | .algolia-autocomplete .algolia-docsearch-footer { 114 | width: 110px; 115 | height: 20px; 116 | z-index: 3; 117 | margin-top: 10.66667px; 118 | float: right; 119 | font-size: 0; 120 | line-height: 0; 121 | } 122 | 123 | .algolia-autocomplete .algolia-docsearch-footer--logo { 124 | background-image: url("data:image/svg+xml;utf8,"); 125 | background-repeat: no-repeat; 126 | background-position: 50%; 127 | background-size: 100%; 128 | overflow: hidden; 129 | text-indent: -9000px; 130 | width: 100%; 131 | height: 100%; 132 | display: block; 133 | transform: translate(-8px); 134 | } 135 | 136 | .algolia-autocomplete .algolia-docsearch-suggestion--highlight { 137 | color: #FF8C00; 138 | background: rgba(232, 189, 54, 0.1) 139 | } 140 | 141 | 142 | .algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { 143 | box-shadow: inset 0 -2px 0 0 rgba(105, 105, 105, .5) 144 | } 145 | 146 | .algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { 147 | background-color: rgba(192, 192, 192, .15) 148 | } 149 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Data From Semantic Scholar Leightweight API • semanticscholar 9 | 10 | 11 | 12 | 13 | 14 | 15 | 22 | 26 | 27 | 28 |
    29 |
    69 | 70 | 71 | 72 | 73 |
    74 |
    75 |
    76 | 78 | 79 | 80 |

    The goal of semanticscholar is to offer data access to data from Semantic Scholar through their lightweight API which can provide data on publications and authors. Semantic Scholar is a free, non-profit academic search and discovery engine whose mission is to empower researchers.

    81 |
    82 |

    83 | Installation

    84 |

    You can install the current version of semanticscholar from GitHub with:

    85 |
     86 | #install.packages("devtools")
     87 | devtools::install_github("kth-library/semanticscholar", dependencies = TRUE)
    88 |
    89 |
    90 |

    91 | Example

    92 |

    This is a basic example which shows you how to get information for papers and authors:

    93 |
     94 | library(semanticscholar)
     95 | library(dplyr)
     96 | #> 
     97 | #> Attaching package: 'dplyr'
     98 | #> The following objects are masked from 'package:stats':
     99 | #> 
    100 | #>     filter, lag
    101 | #> The following objects are masked from 'package:base':
    102 | #> 
    103 | #>     intersect, setdiff, setequal, union
    104 | suppressPackageStartupMessages(library(purrr))
    105 | library(knitr)
    106 | 
    107 | # get a paper using an identifier
    108 | paper <- S2_paper("arXiv:1705.10311", include_unknown_refs = TRUE)
    109 | 
    110 | # authors on that paper
    111 | authors <- paper$authors
    112 | 
    113 | # for one of the authors
    114 | author_ids <- authors$authorId
    115 | author <- S2_author(author_ids[1])
    116 | 
    117 | # list some of the papers
    118 | papers <- 
    119 |   author$papers %>% 
    120 |   select(title, year)
    121 | 
    122 | papers %>% head(5) %>% knitr::kable()
    123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 |
    titleyear
    Optimal Multiple Surface Segmentation With Shape and Context Priors2013
    Optimal Co-Segmentation of Tumor in PET-CT Images With Context Information2013
    Error-Tolerant Scribbles Based Interactive Image Segmentation2014
    Dimensional music emotion recognition by valence-arousal regression2016
    MASCG: Multi-Atlas Segmentation Constrained Graph method for accurate segmentation of hip CT images2015
    155 |
    156 | # get data from several identifiers for importing into Zotero
    157 | ids <- c("10.1038/nrn3241", "CorpusID:37220927")
    158 | my_refs <- zotero_references(ids)
    159 | 
    160 | # this data can now be imported via the Zetero API using https://github.com/giocomai/zoteroR
    161 | # showing data form the first record
    162 | my_refs[[1]]$journalArticle %>% glimpse()
    163 | #> Rows: 1
    164 | #> Columns: 6
    165 | #> $ title            <chr> "The origin of extracellular fields and currents — E…
    166 | #> $ DOI              <chr> "10.1038/nrn3241"
    167 | #> $ URL              <chr> "https://www.semanticscholar.org/paper/da82f8e6ff009…
    168 | #> $ abstractNote     <chr> "Neuronal activity in the brain gives rise to transm…
    169 | #> $ publicationTitle <chr> "Nature Reviews Neuroscience"
    170 | #> $ date             <int> 2012
    171 | my_refs[[2]]$creators %>% knitr::kable()
    172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 |
    creatorTypefirstNamelastName
    authorG.Kawchuk
    authorN.Prasad
    authorR.Chamberlain
    authorA.Klymkiv
    authorL.Peter
    206 |
    207 |
    208 |

    209 | Rate limits and endpoints

    210 |

    By default the rate limit allows 100 request per 5 minute period. This allows for making new requests every 3-4 seconds.

    211 |

    By requesting an API key from Semantic Scholar, this rate can be faster, such as 100 requests per second. If you want to use an API key provided by Semantic Scholar, then edit the ~/.Renviron file to add the key as a value for an environment variable SEMANTICSCHOLAR_API. This R package will then use API endpoints which are faster, with higher rate limits than the regular API endpoints.

    212 |

    The rate limit and API base URL endpoint can be verified:

    213 |
    214 | S2_api()
    215 | #> [1] "https://partner.semanticscholar.org/"
    216 | S2_ratelimit()
    217 | #> [1] 0.01010101
    218 |
    219 |
    220 |

    221 | Data source attribution

    222 |

    When data from semanticscholar is displayed publicly, this attribution also needs to be displayed:

    223 |

    Data source: Semantic Scholar API https://partner.semanticscholar.org/?utm_source=api

    224 |
    225 |
    226 |
    227 | 228 | 259 |
    260 | 261 | 262 | 271 |
    272 | 273 | 274 | 275 | 276 | 277 | 278 | -------------------------------------------------------------------------------- /R/api.R: -------------------------------------------------------------------------------- 1 | #file.edit("~/.Renviron") 2 | #readRenviron("~/.Renviron") 3 | 4 | # author/batch 5 | # author/search 6 | # author/{author_id} 7 | # paper/autocomplete?query={query} 8 | # paper/batch 9 | # paper/search 10 | # paper/search/bulk 11 | # paper/{author_id}/papers 12 | # paper/{paper_id} 13 | # paper/{paper_id}/authors 14 | # paper/{paper_id}/citations 15 | # paper/{paper_id}/references 16 | # /recommendations/v1/papers/ 17 | # /recommendations/v1/papers/forpaper/{paper_id} 18 | 19 | cfg <- function() { 20 | 21 | res <- list( 22 | S2_api = "https://api.semanticscholar.org/", 23 | S2_ratelimit = round((5 * 60) / (100 - 1), digits = 2) 24 | ) 25 | 26 | if (Sys.getenv("SEMANTICSCHOLAR_API") != "") { 27 | res$S2_key <- Sys.getenv("SEMANTICSCHOLAR_API") 28 | res$S2_api <- "https://api.semanticscholar.org/" 29 | res$S2_ratelimit <- 1 / (100 - 1) # for approx 100 requests per second 30 | } 31 | 32 | return (res) 33 | } 34 | 35 | #' Endpoint used for requests to Semantic Scholar API 36 | #' 37 | #' When environment variable SEMANTICSCHOLAR_API is set to a valid API key this 38 | #' value differs as endpoints allowing higher rate limits are being used. 39 | #' @export 40 | S2_api <- function() 41 | cfg()$S2_api 42 | 43 | #' Rate limit for API calls 44 | #' 45 | #' The minimum interval in seconds between requests to the API. 46 | #' 47 | #' When environment variable SEMANTICSCHOLAR_API is set to a valid API key this 48 | #' value can be approx 0.01 (for 100 requests per second) but if no API key is 49 | #' used, the default value will be around 3.5 (allowing a maximum of 100 requests per 5 minutes) 50 | #' @export 51 | S2_ratelimit <- function() 52 | cfg()$S2_ratelimit 53 | 54 | #' Attribution 55 | #' 56 | #' Use this attribution whenever data from the API is publicly displayed 57 | #' 58 | #' @details Semantic Scholar provides a RESTful API for convenient linking 59 | #' to Semantic Scholar pages and pulling information about individual records 60 | #' on demand. When publicly displaying data from this API, 61 | #' please incorporate the Semantic Scholar name and logo and point back to 62 | #' Semantic Scholar at https://www.semanticscholar.org/ with 63 | #' a utm_source=api UTM parameter. 64 | #' @export 65 | S2_attribution <- function() { 66 | sprintf( 67 | "Data source: Semantic Scholar API\n%s?utm_source=api\n%s", S2_api(), 68 | "Data license agreement: http://s2-public-api-prod.us-west-2.elasticbeanstalk.com/license/") 69 | } 70 | 71 | #' Retrieve paper information 72 | #' 73 | #' This function retrieves Semantic Scholar data for a paper 74 | #' given its identifier 75 | #' @param identifier string with identifier 76 | #' @param include_unknown_refs logical, Default: FALSE 77 | #' @details 78 | #' Example of Accessible Paper Identifiers: 79 | #' - S2 Paper ID : 0796f6cd7f0403a854d67d525e9b32af3b277331 80 | #' - DOI : 10.1038/nrn3241 81 | #' - ArXiv ID : arXiv:1705.10311 82 | #' - MAG ID : MAG:112218234 83 | #' - ACL ID : ACL:W12-3903 84 | #' - PubMed ID : PMID:19872477 85 | #' - Corpus ID : CorpusID:37220927 86 | #' 87 | #' S2 is an abbreviation for Semantic Scholar 88 | #' MAG is an abbreviation for Microsoft Academic Graph 89 | #' 90 | #' @return list representing S2 paper object 91 | #' @examples 92 | #' \dontrun{ 93 | #' S2_paper("fb5d1bb23724d9a5a5eae036a2e3cf291cac2c1b") 94 | #' } 95 | #' @importFrom httr GET content status_code 96 | #' @importFrom jsonlite fromJSON 97 | #' @export 98 | S2_paper <- function(identifier, include_unknown_refs = FALSE) { 99 | 100 | q <- NULL 101 | 102 | if (include_unknown_refs) 103 | q <- list(include_unknown_refs = "true") 104 | 105 | key <- cfg()$S2_key 106 | api <- S2_api() 107 | 108 | if (!is.null(key) && nchar(key) > 10) { 109 | res <- httr::GET(url = api, httr::add_headers(`x-api-key` = key), 110 | path = sprintf("graph/v1/paper/%s", identifier), query = q) 111 | } else { 112 | res <- httr::GET(url = api, 113 | path = sprintf("graph/v1/paper/%s", identifier), query = q) 114 | } 115 | 116 | if (status_code(res) == 200) { 117 | res <- jsonlite::fromJSON( 118 | httr::content(res, as = "text", encoding = "utf-8"), 119 | simplifyDataFrame = TRUE 120 | ) 121 | res <- as.data.frame(res) 122 | class(res) <- c("tbl_df", "tbl", "data.frame") 123 | return(res) 124 | } 125 | 126 | if (status_code(res) == 429) 127 | stop("HTTP status 429 Too Many Requests. Please wait before trying again.") 128 | 129 | stop("HTTP status", status_code(res)) 130 | 131 | # list( 132 | # abstract = purrr::pluck(x, "abstract"), 133 | # authors = purrr::pluck(x, "authors") %>% purrr::map_df(dplyr::as_tibble), 134 | # citations_authors = purrr::pluck(x, "citations", "authors") %>% purrr::map_df(dplyr::as_tibble) 135 | # ) 136 | } 137 | 138 | 139 | #' Retrieve author information 140 | #' 141 | #' This function retrieves Semantic Scholar data for 142 | #' an author given the S2Author identifier 143 | #' @param S2AuthorId string with author identifier 144 | #' @details 145 | #' Example of Accessible Paper Identifiers: 146 | #' - S2 Author ID : 1741101 147 | #' @return list representing author object 148 | #' @examples 149 | #' \dontrun{ 150 | #' S2_author(1741101) 151 | #' } 152 | #' @importFrom httr GET status_code content 153 | #' @importFrom jsonlite fromJSON 154 | #' @export 155 | S2_author <- function(S2AuthorId) { 156 | 157 | identifier <- S2AuthorId 158 | key <- cfg()$S2_key 159 | api <- S2_api() 160 | 161 | if (!is.null(key) && nchar(key) > 10) { 162 | res <- httr::GET(url = api, httr::add_headers(`x-api-key` = key), 163 | path = sprintf("graph/v1/author/%s", identifier)) 164 | } else { 165 | res <- httr::GET(url = S2_api(), 166 | path = sprintf("graph/v1/author/%s", identifier)) 167 | } 168 | 169 | if (status_code(res) == 200) 170 | return(jsonlite::fromJSON(httr::content(res, as = "text", encoding = "utf-8"))) 171 | 172 | if (status_code(res) == 429) 173 | stop("HTTP status 429 Too Many Requests (> 100 in 5 mins). Please wait 5 minutes.") 174 | 175 | stop("HTTP status", status_code(res)) 176 | 177 | } 178 | 179 | #' 180 | #' This function retrieves Semantic Scholar data for 181 | #' an author given the S2Author identifier 182 | #' @param S2AuthorId string with author identifier 183 | #' @param details one of "authors", "citations" or "references" 184 | #' @param offset integer paging offset 185 | #' @param limit integer paging length 186 | #' @param fields extra fields to include, for example "title,authors" 187 | #' @details 188 | #' Example of Accessible Paper Identifiers: 189 | #' - S2 Author ID : 1681232 190 | #' @return list representing author object 191 | #' @examples 192 | #' \dontrun{ 193 | #' S2_author(1681232) 194 | #' S2_author2(1681232, fields="affiliations,aliases,externalIds") 195 | #' S2_author2(1681232, fields="paperId,externalIds", details = "papers", offset=0, limit = 100) 196 | #' } 197 | #' @importFrom httr GET status_code content 198 | #' @importFrom jsonlite fromJSON 199 | #' @export 200 | S2_author2 <- function( 201 | S2AuthorId, details=c("papers"), offset = 0, limit = 10, fields = NULL) { 202 | 203 | #https://api.semanticscholar.org/graph/v1/author/1681232?fields=affiliations,aliases,externalIds 204 | 205 | identifier <- S2AuthorId 206 | key <- cfg()$S2_key 207 | api <- S2_api() 208 | 209 | if (missing(details)) { 210 | qpath <- sprintf("graph/v1/author/%s", identifier) 211 | } else { 212 | qpath <- sprintf("graph/v1/author/%s/%s", identifier, match.arg(details)) 213 | } 214 | 215 | if (!missing(fields)) { 216 | if (!missing(details) && !is.null(fields) && !validate_fields(fields, "author_papers")) 217 | stop("Invalid fields") 218 | if (missing(details) && !validate_fields(fields, "author")) 219 | stop("Invalid fields") 220 | } 221 | 222 | q <- list(offset = offset, limit = limit, fields = fields) 223 | 224 | if (!is.null(key) && nchar(key) > 10) { 225 | res <- httr::GET(url = api, httr::add_headers(`x-api-key` = key), 226 | path = qpath, 227 | query = q) 228 | } else { 229 | res <- httr::GET(url = S2_api(), 230 | path = qpath, 231 | query = q) 232 | } 233 | 234 | if (status_code(res) == 200) { 235 | res <- jsonlite::fromJSON( 236 | httr::content(res, as = "text", encoding = "utf-8") 237 | ) 238 | # TODO: fix this 239 | #class(res[[details]]) <- c("tbl_df", "tbl", "data.frame") 240 | return(res) 241 | } 242 | 243 | if (status_code(res) == 429) 244 | stop("HTTP status 429 Too Many Requests (> 100 in 5 mins). Please wait 5 minutes.") 245 | 246 | if (status_code(res) == 400) 247 | stop("HTTP status 400 Bad Query Parameters.") 248 | 249 | if (status_code(res) == 404) 250 | stop("HTTP status 404 Bad Identifier.") 251 | 252 | stop("HTTP status", status_code(res)) 253 | 254 | } 255 | 256 | #' This function retrieves Semantic Scholar data for 257 | #' a keyword search 258 | #' @param keyword string with keywords to search for, supports AND and OR and 259 | #' inclusion and exclusion of terms, for example "+Epidemic +Modeling +Canada -COVID" 260 | #' @param offset integer paging offset 261 | #' @param limit integer paging length 262 | #' @param fields extra fields to include, for example "title,authors" 263 | #' @return list representing paper objects 264 | #' @examples 265 | #' \dontrun{ 266 | #' S2_search_papers(keyword = "literature graph") 267 | #' } 268 | #' @importFrom httr GET status_code content 269 | #' @importFrom jsonlite fromJSON 270 | #' @export 271 | S2_search_papers <- function(keyword, offset = 0, limit = 10, fields = NULL) { 272 | #http://api.semanticscholar.org/graph/v1/paper/search?query=literature+graph 273 | #https://api.semanticscholar.org/graph/v1/author/1681232?fields=affiliations,aliases,externalIds 274 | 275 | q <- keyword 276 | key <- cfg()$S2_key 277 | api <- S2_api() 278 | 279 | if (!is.null(fields) && !missing(fields)) { 280 | if (!validate_fields(fields, "paper_search")) 281 | stop("Invalid fields requested.") 282 | } 283 | 284 | if (!is.null(key) && nchar(key) > 10) { 285 | res <- httr::GET(url = api, httr::add_headers(`x-api-key` = key), 286 | path = "graph/v1/paper/search", 287 | query = list(query = q, offset = offset, limit = limit, fields = fields)) 288 | } else { 289 | res <- httr::GET(url = S2_api(), 290 | path = "graph/v1/paper/search", 291 | query = list(query = q, offset = offset, limit = limit, fields = fields)) 292 | } 293 | 294 | if (status_code(res) == 200) { 295 | res <- jsonlite::fromJSON( 296 | httr::content(res, as = "text", encoding = "utf-8") 297 | ) 298 | if (length(res$data) > 0) { 299 | class(res$data) <- c("tbl_df", "tbl", "data.frame") 300 | } 301 | return(res) 302 | } 303 | 304 | if (status_code(res) == 429) 305 | stop("HTTP status 429 Too Many Requests (> 100 in 5 mins). Please wait 5 minutes.") 306 | 307 | if (status_code(res) == 400) 308 | stop("HTTP status 400 Bad Query Parameters.") 309 | 310 | stop("HTTP status", status_code(res)) 311 | 312 | } 313 | 314 | #' This function retrieves details about a paper's authors 315 | #' @param identifier string with keywords to search for 316 | #' @param details one of "authors", "citations" or "references" 317 | #' @param offset integer paging offset 318 | #' @param limit integer paging length 319 | #' @param fields extra fields to include, for example "title,authors" 320 | #' @return list representing paper objects 321 | #' @examples 322 | #' \dontrun{ 323 | #' S2_paper2(identifier = "649def34f8be52c8b66281af98ae884c09aef38b") 324 | #' } 325 | #' @importFrom httr GET status_code content 326 | #' @importFrom jsonlite fromJSON 327 | #' @export 328 | S2_paper2 <- function(identifier, details=c("authors", "citations", "references"), 329 | offset = 0, limit = 10, fields = NULL) { 330 | 331 | key <- cfg()$S2_key 332 | api <- S2_api() 333 | 334 | if (missing(details)) { 335 | qpath <- sprintf("graph/v1/paper/%s", identifier) 336 | } else { 337 | qpath <- sprintf("graph/v1/paper/%s/%s", identifier, match.arg(details)) 338 | } 339 | 340 | if (!missing(details)) { 341 | if (!is.null(fields) && !validate_fields(fields, rel = paste0("paper_", details))) 342 | stop("Invalid fields.") 343 | } else if (!is.null(fields)) { 344 | if (!validate_fields(fields, rel = "paper")) 345 | stop("Invalid fields") 346 | } 347 | 348 | q <- list(offset = offset, limit = limit, fields = fields) 349 | 350 | if (!is.null(key) && nchar(key) > 10) { 351 | res <- httr::GET(url = api, httr::add_headers(`x-api-key` = key), 352 | path = qpath, 353 | query = q 354 | ) 355 | } else { 356 | res <- httr::GET(url = S2_api(), 357 | path = qpath, 358 | query = q 359 | ) 360 | } 361 | 362 | if (status_code(res) == 200) { 363 | res <- jsonlite::fromJSON( 364 | httr::content(res, as = "text", encoding = "utf-8") 365 | ) 366 | # TODO: sometimes we have differently named slots... 367 | #class(res[[details]]) <- c("tbl_df", "tbl", "data.frame") 368 | return(res) 369 | } 370 | 371 | if (status_code(res) == 429) 372 | stop("HTTP status 429 Too Many Requests (> 100 in 5 mins). Please wait 5 minutes.") 373 | 374 | if (status_code(res) == 400) 375 | stop("HTTP status 400 Bad Query Parameters.") 376 | 377 | if (status_code(res) == 404) 378 | stop("HTTP status 404 Bad Identifier.") 379 | 380 | stop("HTTP status", status_code(res)) 381 | } 382 | 383 | S2_author_fields <- function() { 384 | readLines(textConnection("authorId 385 | externalIds 386 | url 387 | name 388 | aliases 389 | affiliations 390 | homepage 391 | homepage 392 | paperCount 393 | citationCount 394 | hIndex 395 | papers 396 | papers.paperId 397 | papers.externalIds 398 | papers.url 399 | papers.title 400 | papers.abstract 401 | papers.venue 402 | papers.year 403 | papers.referenceCount 404 | papers.citationCount 405 | papers.influentialCitationCount 406 | papers.isOpenAccess 407 | papers.fieldsOfStudy 408 | papers.authors")) 409 | } 410 | 411 | S2_author_papers_fields <- function() { 412 | readLines(textConnection("paperId 413 | externalIds 414 | url 415 | title 416 | abstract 417 | venue 418 | year 419 | referenceCount 420 | citationCount 421 | influentialCitationCount 422 | isOpenAccess 423 | fieldsOfStudy 424 | authors 425 | citations 426 | citations.paperId 427 | citations.url 428 | citations.title 429 | citations.venue 430 | citations.year 431 | citations.authors 432 | references 433 | references.paperId 434 | references.url 435 | references.title 436 | references.venue 437 | references.year 438 | references.authors")) 439 | } 440 | 441 | S2_paper_search_fields <- function() { 442 | readLines(textConnection("paperId 443 | externalIds 444 | url 445 | title 446 | abstract 447 | venue 448 | year 449 | referenceCount 450 | citationCount 451 | influentialCitationCount 452 | isOpenAccess 453 | fieldsOfStudy 454 | authors 455 | authors.authorId 456 | authors.name")) 457 | } 458 | 459 | S2_paper_fields <- function() { 460 | readLines(textConnection("paperId 461 | externalIds 462 | url 463 | title 464 | abstract 465 | venue 466 | year 467 | referenceCount 468 | citationCount 469 | influentialCitationCount 470 | isOpenAccess 471 | fieldsOfStudy 472 | s2FieldsOfStudy 473 | publicationDate 474 | authors 475 | authors.authorId 476 | authors.externalIds 477 | authors.url 478 | authors.name 479 | authors.affiliations 480 | authors.homepage 481 | authors.paperCount 482 | authors.citationCount 483 | authors.hIndex 484 | citations 485 | citations.paperId 486 | citations.url 487 | citations.title 488 | citations.abstract 489 | citations.venue 490 | citations.year 491 | citations.referenceCount 492 | citations.influentialCitationCount 493 | citations.isOpenAccess 494 | citations.authors 495 | references 496 | references.paperId 497 | references.url 498 | references.title 499 | references.venue 500 | references.year 501 | references.referenceCount 502 | references.citationCount 503 | references.influentialCitationCount 504 | references.isOpenAccess 505 | references.authors 506 | embedding 507 | tldr 508 | ")) 509 | } 510 | 511 | S2_paper_authors_fields <- function() { 512 | readLines(textConnection("authorId 513 | externalIds 514 | url 515 | name 516 | affiliations 517 | homepage 518 | paperCount 519 | citationCount 520 | hIndex 521 | papers 522 | papers.paperId 523 | papers.externalIds 524 | papers.url 525 | papers.title 526 | papers.abstract 527 | papers.venue 528 | papers.year 529 | papers.referenceCount 530 | papers.citationCount 531 | papers.influentialCitationCount 532 | papers.isOpenAccess 533 | papers.fieldsOfStudy 534 | papers.s2FieldsOfStudy 535 | papers.publicationDate 536 | papers.authors")) 537 | } 538 | 539 | S2_paper_citations_fields <- function() { 540 | readLines(textConnection("contexts 541 | intents 542 | isInfluential 543 | externalIds 544 | citingpaper.url 545 | citingpaper.title 546 | citingpaper.abstract 547 | citingpaper.venue 548 | citingpaper.year 549 | citingpaper.referenceCount 550 | citingpaper.citationCount 551 | citingpaper.influentialCitationCount 552 | citingpaper.isOpenAccess 553 | citingpaper.fieldsOfStudy 554 | citingpaper.authors")) 555 | } 556 | 557 | S2_paper_references_fields <- function() { 558 | readLines(textConnection("contexts 559 | intents 560 | isInfluential 561 | citedPaper.externalIds 562 | citedPaper.url 563 | citedPaper.title 564 | citedPaper.abstract 565 | citedPaper.venue 566 | citedPaper.year 567 | citedPaper.referenceCount 568 | citedPaper.citationCount 569 | citedPaper.influentialCitationCount 570 | citedPaper.isOpenAccess 571 | citedPaper.fieldsOfStudy 572 | citedPaper.s2FieldsOfStudy 573 | citedPaper.publicationDate 574 | citedPaper.authors")) 575 | } 576 | 577 | validate_fields <- function(fields, 578 | rel = c("author", "author_papers", 579 | "paper_search", "paper", 580 | "paper_authors", "paper_citations", "paper_references")) { 581 | 582 | type <- match.arg(rel) 583 | 584 | fn <- unlist(strsplit(fields, ",")) 585 | 586 | is_ok <- function(x, y) all(x %in% y) 587 | 588 | fields <- switch(type, 589 | "author" = S2_author_fields(), 590 | "author_papers" = S2_author_papers_fields(), 591 | "paper" = S2_paper_fields(), 592 | "paper_search" = S2_paper_search_fields(), 593 | "paper_authors" = S2_paper_authors_fields(), 594 | "paper_citations" = S2_paper_citations_fields(), 595 | "paper_references" = S2_paper_references_fields() 596 | ) 597 | 598 | if (isTRUE(is_ok(fn, fields))) { 599 | return (invisible(TRUE)) 600 | } 601 | 602 | idx <- which(fn %in% fields) 603 | valid <- fn[idx] 604 | invalid <- setdiff(fn, fields) 605 | message("Please provide comma separated (no spaces) string with fields") 606 | message("Valid: ", paste0(collapse=",", valid)) 607 | message("Invalid: ", paste0(collapse=",", invalid)) 608 | message("Available: ") 609 | print(setdiff(fields, fn)) 610 | return (invisible(FALSE)) 611 | } 612 | 613 | #' Valid fields available for use in API calls 614 | #' @export 615 | S2_fields <- function() { 616 | list( 617 | author = S2_author_fields(), 618 | author_papers = S2_author_papers_fields(), 619 | paper_search = S2_paper_search_fields(), 620 | paper_authors = S2_paper_authors_fields(), 621 | paper_citations = S2_paper_citations_fields(), 622 | paper_references = S2_paper_references_fields() 623 | ) 624 | } 625 | 626 | # S2_releases <- function() { 627 | # "https://api.semanticscholar.org/datasets/v1/release" |> 628 | # httr::GET() |> 629 | # httr::content() |> 630 | # unlist() |> sort(TRUE) |> 631 | # tibble::as_tibble_col("release") 632 | # } 633 | 634 | # S2_release_datasets <- function(release_id) { 635 | # res <- 636 | # "https://api.semanticscholar.org/datasets/v1/release/%s" |> 637 | # sprintf(release_id) |> 638 | # httr::GET() |> 639 | # httr::content() 640 | 641 | # dplyr::bind_cols( 642 | # release_id = res$release_id, 643 | # res$datasets |> purrr::map_df(tibble::as_tibble) |> 644 | # dplyr::rename(dataset_name = "name") 645 | # ) 646 | 647 | # } 648 | 649 | # S2_dataset_urls <- function(release_id, dataset_name) { 650 | 651 | # res <- 652 | # "https://api.semanticscholar.org/datasets/v1/release/%s/dataset/%s" |> 653 | # sprintf(release_id, dataset_name) |> 654 | # httr::GET() |> 655 | # httr::content() 656 | 657 | # res 658 | 659 | # } 660 | 661 | --------------------------------------------------------------------------------