如何允许递归函数检查以前处理过的字符串

时间:2019-02-28 11:22:48

标签: r

我有一个递归函数,它查找一个字符串并根据该字符串获取一个数据帧。有时我会进入无限循环,所以我想保留所有已检查过的字符串的列表。我怎样才能做到这一点?这是功能。我想存储所有名为elem

的字符串
 get_all_dfs_rec <- function(df, my_env) {
    lapply(df$relatedIdEx, function(elem) {    
        next_df <- myGIConcepts(elem)
        next_df_list<-list(next_df,my_env)
        if (!is.na(next_df_list)) {
          rm(list = elem, envir = my_env)
          unlist(get_all_dfs_rec(next_df_list[[1]], my_env), FALSE)
          } else {
          list(setNames(df, c("col1", "col2")))
        }
    })
  }

1 个答案:

答案 0 :(得分:1)

请尝试以下操作,该操作会初始化一个空向量,并在每次迭代时将“ elem”的字符表示简单地附加到向量中。该向量保存在调用函数的环境中,因此使用“ <<-”运算符从lapply()中建立的隐含函数的环境内对其进行写入。从理论上讲,一旦遇到所有可能的查询名称,该函数最终将返回NULL,并将结果沿调用链向上传递。

library(tidyverse)
already_lookedup <- c()
get_all_dfs <- function(df) {
   lapply(df[, 1], function(elem) {
      print(paste("Looking for element", elem))
      if (as.character(unlist(elem)) %in% already_lookedup) {
        print(paste("Already looked up ",elem," and skipping!"))
        return (NULL)
      } else {
        already_lookedup <<- c(already_lookedup,as.character(unlist(elem)))
      }
      # use mget because we can use ifnotfound despite we are requesting only one element
      next_df <- mget(elem, env = .GlobalEnv, ifnotfound = NA)
      if (!is.na(next_df)) {
         unlist(get_all_dfs(next_df[[1]]), F)
      } else {
         list(setNames(df, c("col1", "col2")))
      }
    })
}

flatten_dfr(get_all_dfs(df1)) %>% unique()