Как выполнить поиск по родительским и дочерним фреймам данных - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть вопрос об итеративном поиске.Я пытаюсь извлечь текст из текстовой базы данных (онтологии), которая связывает слова друг с другом, так что, когда я ищу одно слово, оно дает мне все дочерние слова (например, «эндоскопия» даст мне все подтипы эндоскопии, например, «колоноскопия "," гастроскопия "и т. д.)

Когда я смотрю слово, я возвращаю фрейм данных со всеми связанными словами.Затем я хочу просмотреть все эти слова в возвращенном фрейме данных и увидеть связанные с ними дочерние слова и т. Д., Пока поиск не будет исчерпан.Чтобы обеспечить минимальный воспроизводимый пример, у меня есть три кадра данных следующим образом: Первый кадр данных - это возвращение из исходного поискового запроса (порядок выполнения не имеет значения, поэтому детали этой функции не включены)

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"

Я не включил остальные поиски для краткости.

Iпоэтому я хочу получить функцию, которая ищет каждую таблицу до тех пор, пока ей не будет возвращен фрейм данных, и если фрейм данных будет возвращен, то это используется для поиска.Как только искомый кадр данных достигает конца условий поиска, он должен вернуться к родительской таблице, чтобы продолжить поиск.Я хотел бы сохранить все возвращенные фреймы данных.

Я полагаю, что этого можно добиться с помощью чего-то вроде

lapply(df1$Numsdf1,function(x) lookup(x))

, где lookup выбирает фрейм данных и сохраняет результат.Проблема состоит в том, что это работает для одного уровня поиска, но как мне затем разрешить поиск и хранение для последующих дочерних таблиц (которые могут быть намного больше слоев, чем показано здесь)

Результат для примера выше долженbe:

Конечный фрейм данных:

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"

, который, я полагаю, является всего лишь rbind всех строк.Проблема, которую я имею, состоит в том, как применить lapply с моей функцией поиска и убедиться, что поиск выполняется рекурсивно через родительскую и дочернюю таблицы, а также как убедиться, что поиск в родительской таблице перезапущен (в том месте, где он оставлен)когда дочерний поиск завершен (то есть все строки в столбце Nums были найдены)

1 Ответ

0 голосов
/ 27 февраля 2019

Это звучит как проблема рекурсии.Вы просматриваете все элементы первого столбца в кадре данных.Если вы найдете совпадение с этим именем (т. Е. В глобальной среде есть фрейм данных с этим именем), вы вызываете функцию с этим новым фреймом данных, и рекурсия начинается снова.Если вы не нашли фрейм данных, вы просто возвращаете фрейм данных.

Обратите внимание, что окончательный вывод будет вложенным списком, а некоторые из фреймов данных появятся более одного раза.Вы можете использовать комбинацию unlist, do.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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...