首页 > 解决方案 > 奇怪的 R 包行为:“找不到函数”

问题描述

我有一些在包之外可以正常工作的功能,但是当我将它放入包中时,devtools::load_all 并尝试运行其中一个函数 (DTL_similarity_search_results_fast) ,另一个应该由包加载的函数 (DTL_similarity_search)在 DTL_similarity_search_results_fast 内运行时找不到。

代码是:

messagef <- function(...) message(sprintf(...))
printf <- function(...) print(sprintf(...))

pattern_to_vec <- function(pattern, as_int = F, keep_list = FALSE) {
  ret <- strsplit(pattern, ",")
  if(length(pattern) == 1 && !keep_list)
    ret <- ret[[1]]
  if(as_int){
    ret <- lapply(ret, as.integer)
  }
  ret
}


DTL_similarity_search <- function(search_pattern = "1,2,1,2,1,2,1,2",
                                  transformation = "interval",
                                  database_names = "dtl,wjazzd,omnibook",
                                  metadata_filters = '{"dtl": {}, "wjazzd": {}, "esac": {}, "omnibook": {}}',
                                  filter_category = "0",
                                  minimum_similarity = 1.0,
                                  max_edit_distance = NA,
                                  max_length_difference = 0) {
  url <- suppressWarnings(httr::modify_url("https://staging-dtl-pattern-api.hfm-weimar.de/", path = "/patterns/similar"))
  if(is.na(max_edit_distance)){
    max_edit_distance <- purrr::map_int(pattern_to_vec(search_pattern, keep_list = T), length) %>% min()
  }
  messagef("[DTL API] Starting search for %s", search_pattern)
  resp <- suppressWarnings(httr::POST(url, body = list( n_gram = search_pattern,
                                                        transformation = transformation,
                                                        database_names = database_names,
                                                        metadata_filters = metadata_filters,
                                                        filter_category = filter_category,
                                                        minimum_similarity = minimum_similarity,
                                                        max_edit_distance = max_edit_distance,
                                                        max_length_difference = max_length_difference, filter_category = 0),
                                      encode = "form"))
  #browser()
  #print(httr::content(resp, "text"))
  if (httr::http_error(resp)) {
    messagef(
      "[DTL API]  Similarity Search  request failed [%s]\n%s\n<%s>",
      httr::status_code(resp),
      "",#parsed$message,
      ""#parsed$documentation_url
    )
    return(NULL)
  }
  parsed <- jsonlite::fromJSON(httr::content(resp, "text"), simplifyVector = FALSE)
  messagef("[DTL API] Retrieved search ID %s of for pattern %s", parsed$search_id, search_pattern)
  parsed$search_id
}

DTL_get_results <- function(search_id) {
  url <- suppressWarnings(httr::modify_url("http://staging-dtl-pattern-api.hfm-weimar.de/", path = "/patterns/get"))
  #messagef("[DTL API] Retrieving results for search_id %s",  search_id)
  resp <- suppressWarnings(httr::GET(url, query = list(search_id  = search_id)))
  if (httr::http_error(resp)) {
    messagef(
      "[DTL API]  Similarity Search  request failed [%s]\n%s\n<%s>",
      httr::status_code(resp),
      "",#parsed$message,
      ""#parsed$documentation_url
    )
    return(NULL)
  }
  print(httr::content(resp, "text"))
  #browser()

  parsed <- jsonlite::fromJSON(httr::content(resp, "text"), simplifyVector = FALSE)
  messagef("[DTL API] Retrieved %s lines for search_id %s", length(parsed), search_id)
  purrr::map_dfr(parsed, function(x){
    if(is.null(x$within_single_phrase)){
      x$within_single_phrase <- FALSE
    }
    #browser()
    tibble::as_tibble(x) %>% dplyr::mutate(melid = as.character(melid))
  })
}

DTL_similarity_search_results <- function(search_patterns = "1,2,1,2,1,2,1,2",
                                          transformation = "interval",
                                          database_names = "dtl,wjazzd,omnibook",
                                          metadata_filters = '{"dtl": {}, "wjazzd": {}, "esac": {}, "omnibook": {}}',
                                          filter_category = "0",
                                          minimum_similarity = 1.0,
                                          max_edit_distance = NA,
                                          max_length_difference = 0) {
  results <- tibble::tibble()
  if(is.na(max_edit_distance)){
    max_edit_distance <- purrr:::map_int(pattern_to_vec(search_patterns, keep_list = T), length) %>% min()
  }
  for(pattern in search_patterns){
    print('DTL_similarity_search')
    print(DTL_similarity_search)
    search_id <- DTL_similarity_search(pattern,
                                       transformation,
                                       database_names,
                                       metadata_filters,
                                       filter_category,
                                       minimum_similarity,
                                       max_edit_distance = max_edit_distance,
                                       max_length_difference = max_length_difference)
    if(is.null(search_id)){
      next
    }

    ret <- DTL_get_results(search_id)
    if(!is.null(ret) && nrow(ret) > 0){
      ret$search_pattern <- pattern
    }
    results <- dplyr::bind_rows(results, ret)


  }
  #browser()
  if(nrow(results))
    results %>% dplyr::distinct(melid, start, length, .keep_all = T)
}

DTL_similarity_search_results_fast <- function(search_patterns = "1,2,1,2,1,2,1,2",
                                               transformation = "interval",
                                               database_names = "dtl,wjazzd,omnibook",
                                               metadata_filters = '{"dtl": {}, "wjazzd": {}, "esac": {}, "omnibook": {}}',
                                               filter_category = "0",
                                               minimum_similarity = 1.0,
                                               max_edit_distance = NA,
                                               max_length_difference = 0){
  if(is.na(max_edit_distance)){
    max_edit_distance <- purrr::map_int(pattern_to_vec(search_patterns, keep_list = T), length) %>% min()
  }
  future::plan(future::multisession)
  results <- furrr:::future_map_dfr(search_patterns, function(pattern){
    print('DTL_similarity_search2')
    search_id <- DTL_similarity_search(pattern,
                                       transformation,
                                       database_names,
                                       metadata_filters,
                                       filter_category,
                                       minimum_similarity,
                                       max_edit_distance = max_edit_distance,
                                       max_length_difference = max_length_difference)
    if(is.null(search_id)){
      return(tibble::tibble())
    }
    ret <- DTL_get_results(search_id)
    if(!is.null(ret) && nrow(ret) > 0 )ret$search_pattern <- pattern
    ret
  })
  #browser()
  results %>% dplyr::distinct(melid, start, length, .keep_all = TRUE)
}

然后在我尝试运行时 load_all() 之后:

res <- DTL_similarity_search_results_fast()

我得到:

DTL_similarity_search 中的错误(模式、转换、数据库名称,:找不到函数“DTL_similarity_search

但是运行类似的不同功能可以使用相同的过程:

res <- DTL_similarity_search_results()

标签: rr-package

解决方案


推荐阅读