如何通过父和子数据框执行搜索

时间:2019-02-27 12:59:06

标签: r function dataframe search

我有一个关于迭代查找的问题。我试图从文本数据库(一个本体)中提取文本,该数据库将单词彼此关联,以便当我查询一个单词时,它给我所有的子单词(例如“内窥镜检查”会给我所有内窥镜检查的亚型,例如“结肠镜检查”,“胃镜检查”等)。

当我查询单词时,我会得到一个包含所有相关单词的数据框。然后,我想在返回的数据框中查找所有这些单词,并查看其相关的子单词等,直到搜索用尽。为了提供一个最小的可重现示例,我有三个数据框,如下所示:第一个数据框是原始查找查询的返回值(查找的完成方式不相关,因此不包含此函数详细信息)

Numsdf1<-c("C123","C456","C789")
Textdf1<-c("Harry","Bobby","Terry")
df1<-data.frame(Numsdf1,Textdf1,stringsAsFactors=FALSE)

第二个数据帧是查询字符串"C123"

的结果
NumsC123<-c("Coo","Noo","Too")
TextC123<-c("Tim","Slim","Shim")
C123<-data.frame(NumsC123,TextC123,stringsAsFactors=FALSE)

第三个数据帧是查找"Coo"

的结果
NumsCoo<-c("S144","S199","S743")
TextCoo<-c("Ellie","Bellie","Tellie")
Coo<-data.frame(NumsCoo,TextCoo,stringsAsFactors=FALSE)

第四是查找"Noo"

的结果
NumsNoo<-c("GHS","THE","PAA")
TextNoo<-c("Front","Bunt","Shunt")
Noo<-data.frame(NumsNoo,TextNoo,stringsAsFactors=FALSE)

查找"Too"

时不会返回任何内容

为了简洁起见,我没有包括其余的查询内容。

因此,我想派生一个搜索每个表的函数,直到返回一个数据框为止,如果返回了一个数据框,则将其用于搜索。一旦搜索到的数据帧到达查找条件的末尾,则它应返回到父表以继续查找。我想存储所有返回的数据帧。

我想这可以通过像这样

来实现
lapply(df1$Numsdf1,function(x) lookup(x))

其中查找将获取数据帧并存储结果。问题是,这仅适用于一级查找,但是我如何应用后续子表的查找和存储(可能比此处显示的层多得多)

以上示例的结果应为:

最终数据框:

NumsFinal<-c("C123","C456","C789","Coo","Noo","Too","S144","S199","S743","GHS","THE","PAA"
TextFinal<-c("Harry","Bobby","Terry","Tim","Slim","Shim","Ellie","Bellie","Tellie","Front","Bunt","Shunt"

我猜这只是所有行的参考。我遇到的问题是如何对我的查找功能应用lapply并确保通过父表和子表递归完成查找,以及如何确保重新启动父表中的查找(在它的左边)子查找完成后(即Nums列中的所有字符串都已查找)

1 个答案:

答案 0 :(得分:1)

这听起来像递归问题。您可以浏览数据框中第一列的所有元素。如果找到与该名称匹配的名称(即,全局环境中使用该名称的数据框),则使用该新数据框调用该函数,然后递归再次开始。如果找不到数据框,则只需返回数据框。

请注意,最终输出将是一个嵌套列表,并且某些数据帧会出现多次。您可以结合使用unlistdo.call(rbind,..)unique以获得最终结果。

编辑:略微更改了代码,以从调用中获得更方便的数据结构。

library(tidyverse)
get_all_dfs <- function(df) {
   lapply(df[, 1], function(elem) {
      print(paste("Looking for element", 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()

因此搜索路径将为C123 -> Coo -> S144 -> S199 -> S743 -> Noo -> GHS -> THE -> PAA -> Too -> C456 -> C789