首页 > 解决方案 > 如何允许递归函数检查先前处理的字符串

问题描述

我有一个递归函数,它查找一个字符串并根据该字符串获取一个数据帧。有时我会进入无限循环,所以我想保留一个已经检查过的所有字符串的列表。我怎样才能做到这一点?这是功能。我想存储所有调用的字符串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")))
        }
    })
  }

标签: r

解决方案


试试下面的方法,它初始化一个空向量,并在每次迭代时简单地将 'elem' 的字符表示附加到向量中。该向量保存在调用函数的环境中,因此“<<-”运算符用于从 lapply() 中建立的隐含函数的环境中写入它。理论上,一旦遇到所有可能的查找名称,该函数最终将返回 NULL 并将 lapply 的结果向上传递到调用链。

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()

推荐阅读