【问题标题】:R: Unique object name in given environmentR:给定环境中的唯一对象名称
【发布时间】:2021-05-10 01:57:05
【问题描述】:

我有一个函数可以返回一个对象名称向量,它在给定环境中是唯一的:

find_unique_name <- function(nNames, environment) {

  un <- replicate(nNames, paste0(sample(LETTERS, 10), collapse=""))

  while (any(duplicated(un)) | any(un %in% ls(envir = environment))) {

    un <- replicate(nNames, paste0(sample(LETTERS, 10), collapse=""))
  }    

  return(un)
}

我想知道这个函数的速度是否可以提高,因为它在算法中被多次调用。我想知道它是否可以被矢量化,或者至少是否有办法在没有循环的情况下做到这一点。我怀疑这不是找到唯一对象名称向量的最快方法。谢谢!

【问题讨论】:

    标签: r performance loops while-loop vectorization


    【解决方案1】:

    要生成新名称,我建议使用以下而不是 replicate...

    gen_names <- function(nNames) {
      vapply(1:nNames, 
             function(i) {
               paste0(sample(LETTERS, 10), collapse = "")
              }, 
             FUN.VALUE = character(1))
    }
    

    您知道您需要characters,并且您应该使用此信息进行优化。

    在每次迭代中,您都会列出环境中的名称。这不需要每次迭代都完成,因为环境中的名称不会改变。并且知道有多少名称是有效的新名称,您无需在每次迭代时创建nNames,只需创建您需要的差异即可。 所以我建议

    get_unique_name <- function(nNames, environment = .GlobalEnv) {
      
      namesInEnvironment <- ls(envir = environment)
      
      un <- gen_names(nNames)
      un <- unique(un)
      un <- un[!(un %in% namesInEnvironment)]
      
      while(length(un)<nNames) {
        needNamesNr <- nNames - lenth(un)
        un <- c(un,gen_names(needNamesNr))
        un <- unique(un)
        un <- un[!(un %in% namesInEnvironment)]
      }    
      
      return(un[1:nNames])
    }
    

    我做了一些基准测试,下面的名称生成函数要快得多:

    gen_names2 <- function(nNames = 100) {
      apply(matrix(sample(LETTERS,nNames*10,replace = T),ncol = 10),
            1,
            paste0,collapse="")
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-13
      • 1970-01-01
      • 2018-09-10
      • 2023-03-08
      • 2017-12-23
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      • 2016-03-07
      相关资源
      最近更新 更多