1 2 3 4 5 6 7 8 9 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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 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 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
|
## internal function that match the arguments provided to the correct
## row number in the data frame representing the Open Tree Taxonomy
## for a series of matched names.
check_args_match_names <- function(response, row_number, taxon_name, ott_id) {
orig_order <- attr(response, "original_order")
if (is.null(orig_order)) {
stop(
sQuote(substitute(response)), " was not created using ",
sQuote("tnrs_match_names")
)
}
if (missing(row_number) && missing(taxon_name) && missing(ott_id)) {
stop(
"You must specify one of ", sQuote("row_number"),
sQuote("taxon_name"), " or ", sQuote("ott_id")
)
} else if (!missing(row_number) && missing(taxon_name) && missing(ott_id)) {
if (!is.numeric(row_number)) {
stop(sQuote("row_number"), " must be a numeric.")
}
if (!all(row_number %in% orig_order)) {
stop(sQuote("row_number"), " is not a valid row number.")
}
i <- orig_order[row_number]
} else if (missing(row_number) && !missing(taxon_name) && missing(ott_id)) {
if (!is.character(taxon_name)) {
stop(sQuote("taxon_name"), " must be a character.")
}
i <- orig_order[match(tolower(taxon_name), response$search_string)]
if (any(is.na(i))) {
stop("Can't find ", taxon_name)
}
} else if (missing(row_number) && missing(taxon_name) && !missing(ott_id)) {
if (!check_numeric(ott_id)) {
stop(sQuote("ott_id"), " must look like a number.")
}
i <- orig_order[match(ott_id, response$ott_id)]
if (any(is.na(i))) stop("Can't find ", ott_id)
} else {
stop(
"You must use only one of ",
sQuote("row_number"),
sQuote("taxon_name"),
" or ", sQuote("ott_id"), "."
)
}
if (length(i) > 1) {
stop("You must supply a single element for each argument.")
}
i
}
match_row_number <- function(response, row_number, taxon_name, ott_id) {
## all the checks on the validity of the arguments are taken care
## by check_args_match_names()
if (missing(row_number) && missing(taxon_name) &&
missing(ott_id)) {
stop(
"You must specify one of ", sQuote("row_number"), " ",
sQuote("taxon_name"), " ", sQuote("ott_id")
)
} else if (!missing(row_number) && (missing(taxon_name) && missing(ott_id))) {
i <- row_number
} else if (!missing(taxon_name) && (missing(row_number) && missing(ott_id))) {
i <- match(tolower(taxon_name), response[["search_string"]])
} else if (!missing(ott_id) && (missing(row_number) && missing(taxon_name))) {
i <- match(ott_id, response[["ott_id"]])
} else {
stop(
"You must use only one of ", sQuote("row_number"),
" ", sQuote("taxon_name"), " ", sQuote("ott_id")
)
}
if (length(i) > 1) {
stop("You must supply a single element for each argument.")
}
i
}
##' Taxonomic names may have different meanings in different taxonomic
##' contexts, as the same genus name can be applied to animals and
##' plants for instance. Additionally, the meaning of a taxonomic name
##' may have change throughout its history, and may have referred to a
##' different taxon in the past. In such cases, a given names might
##' have multiple matches in the Open Tree Taxonomy. These functions
##' allow users to inspect (and update) alternative meaning of a given
##' name and its current taxonomic status according to the Open Tree
##' Taxonomy.
##'
##' To inspect alternative taxonomic meanings of a given name, you
##' need to provide the object resulting from a call to the
##' tnrs_match_names function, as well as one of either the row number
##' corresponding to the name in this object, the name itself (as used
##' in the original query), or the ott_id listed for this name.
##'
##' To update one of the name, you also need to provide the row number
##' in which the name to be replaced appear or its ott id.
##'
##' @title Inspect and Update alternative matches for a name returned
##' by tnrs_match_names
##' @param response an object generated by the
##' \code{\link{tnrs_match_names}} function
##' @param row_number the row number corresponding to the name to
##' inspect
##' @param taxon_name the taxon name corresponding to the name to
##' inspect
##' @param ott_id the ott id corresponding to the name to inspect
##' @param ... currently ignored
##' @return a data frame
##' @seealso \code{\link{tnrs_match_names}}
##' @examples
##' \dontrun{
##' matched_names <- tnrs_match_names(c("holothuria", "diadema", "boletus"))
##' inspect(matched_names, taxon_name="diadema")
##' new_matched_names <- update(matched_names, taxon_name="diadema",
##' new_ott_id = 631176)
##' new_matched_names
##' }
##' @export
##' @rdname match_names
inspect.match_names <- function(response, row_number, taxon_name, ott_id, ...) {
i <- check_args_match_names(response, row_number, taxon_name, ott_id)
j <- match_row_number(response, row_number, taxon_name, ott_id)
if (attr(response, "has_original_match")[j]) {
res <- attr(response, "original_response")
summary_match <- build_summary_match(res,
res_id = i, match_id = NULL,
initial_creation = FALSE
)
} else {
summary_match <- response[j, ]
}
clean_tnrs_summary(summary_match)
}
##' @export
##' @rdname match_names
inspect <- function(response, ...) UseMethod("inspect")
##' @param object an object created by \code{\link{tnrs_match_names}}
##' @param new_row_number the row number in the output of
##' \code{\link{inspect}} to replace the taxa specified by
##' \code{row_number}, \code{taxon_name}, or \code{ott_id}.
##' @param new_ott_id the ott id of the taxon to replace the taxa
##' specified by \code{row_number}, \code{taxon_name}, or
##' \code{ott_id}.
##' @export
##' @rdname match_names
##' @importFrom stats update
update.match_names <- function(object, row_number, taxon_name, ott_id,
new_row_number, new_ott_id, ...) {
response <- object
i <- check_args_match_names(response, row_number, taxon_name, ott_id)
j <- match_row_number(response, row_number, taxon_name, ott_id)
res <- attr(response, "original_response")
if (!attr(response, "has_original_match")[j]) {
warning(
"There is no match for this name, ",
"so there is nothing to replace it with."
)
return(response)
}
tmpRes <- res$results[[i]]
if (missing(row_number)) {
if (!missing(taxon_name)) {
rnb <- match(tolower(taxon_name), response$search_string)
} else if (!missing(ott_id)) {
rnb <- match(ott_id, response$ott_id)
}
} else {
rnb <- row_number
}
if (missing(new_row_number) && missing(new_ott_id)) {
stop(
"You must specify either ", sQuote("new_row_number"),
" or ", sQuote("new_ott_id")
)
} else if (!missing(new_row_number) && missing(new_ott_id)) {
if (!new_row_number %in% seq_len(length(tmpRes$matches))) {
stop(sQuote("new_row_number"), " is not a valid row number.")
}
j <- new_row_number
} else if (missing(new_row_number) && !missing(new_ott_id)) {
all_ott_id <- sapply(
lapply(
tmpRes[["matches"]],
function(x) x[["taxon"]]
),
function(x) .tax_ott_id(x)
)
j <- match(new_ott_id, all_ott_id)
if (any(is.na(j))) stop("Can't find ", new_ott_id)
} else {
stop(
"You must use only one of ", sQuote("new_row_number"),
" or ", sQuote("new_ott_id")
)
}
if (length(j) > 1) stop("You must supply a single element for each argument")
summ_match <- summary_row_factory(res, res_id = i, match_id = j)
response[rnb, ] <- summ_match
attr(response, "match_id")[rnb] <- j
clean_tnrs_summary(response)
}
## Access the elements for a given match:
## is_synonym, score, nomenclature_code, is_approximate_match, taxon
get_list_element <- function(response, i, list_name) {
list_content <- lapply(
response[["results"]][[i]][["matches"]],
function(x) {
x[[list_name]]
}
)
list_content
}
match_names_method_factory <- function(list_name) {
function(tax, row_number, taxon_name, ott_id, ...) {
response <- tax
res <- attr(response, "original_response")
no_args <- all(c(
missing(row_number), missing(taxon_name),
missing(ott_id)
))
if (no_args) {
res_i <- attr(response, "original_order")[attr(response, "has_original_match")]
ret <- lapply(res_i, function(i) {
get_list_element(res, i, list_name)
})
names(ret) <- sapply(res_i, function(i) {
get_list_element(res, i, "matched_name")[[1]]
})
## ret is already in the correct order so we can use a sequence
## to extract the correct element
ret <- mapply(function(x, i) {
ret[[x]][i]
}, seq_along(ret), attr(response, "match_id")[attr(response, "has_original_match")])
if (all(sapply(ret, length) == 1)) {
ret <- unlist(ret, use.names = TRUE)
}
} else {
i <- check_args_match_names(response, row_number, taxon_name, ott_id)
j <- match_row_number(response, row_number, taxon_name, ott_id)
if (attr(response, "has_original_match")[j]) {
ret <- get_list_element(res, i, list_name)[attr(response, "match_id")[j]]
} else {
ret <- list(
ott_id = NA_character_,
name = response[["search_string"]][j],
unique_name = NA_character_,
rank = NA_character_,
tax_sources = NA_character_,
flags = NA_character_,
synonyms = NA_character_,
is_suppressed = NA_character_
)
ret <- list(ret)
}
}
ret
}
}
match_names_taxon_method_factory <- function(.f) {
function(tax, row_number, taxon_name, ott_id, ...) {
extract_tax_list <- match_names_method_factory("taxon")
tax_info <- extract_tax_list(tax,
row_number = row_number,
taxon_name = taxon_name,
ott_id = ott_id
)
res <- lapply(tax_info, function(x) .f(x))
names(res) <- vapply(tax_info, function(x) .tax_unique_name(x), character(1))
res <- add_otl_class(res, .f)
res
}
}
##' \code{rotl} provides a collection of functions that allows users
##' to extract relevant information from an object generated by
##' \code{\link{tnrs_match_names}} function.
##'
##' These methods optionally accept one of the arguments
##' \code{row_number}, \code{taxon_name} or \code{ott_id} to retrieve
##' the corresponding information for one of the matches in the object
##' returned by the \code{\link{tnrs_match_names}} function.
##'
##' If these arguments are not provided, these methods can return
##' information for the matches currently listed in the object
##' returned by \code{\link{tnrs_match_names}}.
##'
##' @title \code{ott_id} and \code{flags} for taxonomic names matched
##' by \code{tnrs_match_names}
##' @param tax an object returned by \code{\link{tnrs_match_names}}
##' @param row_number the row number corresponding to the name for
##' which to list the synonyms
##' @param taxon_name the taxon name corresponding to the name for
##' which to list the synonyms
##' @param ott_id the ott id corresponding to the name for which to
##' list the synonyms
##' @param ... currently ignored
##' @return A list of the ott ids or flags for the taxonomic names
##' matched with \code{\link{tnrs_match_names}}, for either one or
##' all the names.
##' @examples
##' \dontrun{
##' rsp <- tnrs_match_names(c("Diadema", "Tyrannosaurus"))
##' rsp$ott_id # ott id for match currently in use
##' ott_id(rsp) # similar as above but elements are named
##'
##' ## flags() is useful for instance to determine if a taxon is extinct
##' flags(rsp, taxon_name="Tyrannosaurus")
##' }
##' @export
##' @rdname match_names-methods
ott_id.match_names <- match_names_taxon_method_factory(.tax_ott_id)
##' @export
##' @rdname match_names-methods
flags.match_names <- match_names_taxon_method_factory(.tax_flags)
##' When querying the Taxonomic Name Resolution Services for a
##' particular taxonomic name, the API returns as possible matches all
##' names that include the queried name as a possible synonym. This
##' function allows you to explore other synonyms for an accepted
##' name, and allows you to determine why the name you queried is
##' returning an accepted synonym.
##'
##' To list synonyms for a given taxonomic name, you need to provide
##' the object resulting from a call to the
##' \code{\link{tnrs_match_names}} function, as well as one of either
##' the row number corresponding to the name in this object, the name
##' itself (as used in the original query), or the ott_id listed for
##' this name. Otherwise, the synonyms for all the currently matched
##' names are returned.
##'
##' @title List the synonyms for a given name
##' @param tax a data frame generated by the
##' \code{\link{tnrs_match_names}} function
##' @param row_number the row number corresponding to the name for
##' which to list the synonyms
##' @param taxon_name the taxon name corresponding to the name for
##' which to list the synonyms
##' @param ott_id the ott id corresponding to the name for which to
##' list the synonyms
##' @param ... currently ignored
##' @return a list whose elements are all synonym names (as vectors of
##' character) for the taxonomic names that match the query (the
##' names of the elements of the list).
##' @examples
##' \dontrun{
##' echino <- tnrs_match_names(c("Diadema", "Acanthaster", "Fromia"))
##' ## These 3 calls are identical
##' synonyms(echino, taxon_name="Acanthaster")
##' synonyms(echino, row_number=2)
##' synonyms(echino, ott_id=337928)
##' }
##' @export
synonyms.match_names <- match_names_taxon_method_factory(.tax_synonyms)
##' @export
tax_sources.match_names <- match_names_taxon_method_factory(.tax_sources)
##' @export
tax_rank.match_names <- match_names_taxon_method_factory(.tax_rank)
##' @export
is_suppressed.match_names <- match_names_taxon_method_factory(.tax_is_suppressed)
##' @export
unique_name.match_names <- match_names_taxon_method_factory(.tax_unique_name)
##' @export
tax_name.match_names <- match_names_taxon_method_factory(.tax_name)
|