Заполните не полностью связанные документы (деревья документов) с помощью списка поиска с помощью функции

У меня есть связанные документы (деревья документов), сохраненные в списке (list)

В некоторых деревьях документов есть элементы, которые не завершены (отмечены seach=1). Некоторые деревья могут иметь несколько неполных деревьев, отмеченных search=1.

Я хотел бы расширить/дополнить эти неполные деревья, используя список поиска, который содержит деревья документов (list_lookup), в списке всегда есть только одно соответствующее дерево и list_lookup. level соответствующего дерева документов следует настроить на дерево документов в list.

Пример данных и желаемый результат:

library(tidyverse)

# initial df1, aaa is incomplete (it is in fact linked to other documents, but this information is stored in the lookup list)
 
df1 <- tibble(id_from=c(NA_character_,"111","222","333","444","444","bbb"),
             id_to=c("111","222","333","444","aaa","bbb","ccc"),
             level=c(0,1,2,3,4,4,5),
             search=c(0,0,0,0,1,0,0))
df1
#> # A tibble: 7 × 4
#>   id_from id_to level search
#>   <chr>   <chr> <dbl>  <dbl>
#> 1 <NA>    111       0      0
#> 2 111     222       1      0
#> 3 222     333       2      0
#> 4 333     444       3      0
#> 5 444     aaa       4      1
#> 6 444     bbb       4      0
#> 7 bbb     ccc       5      0


# lookup dfs, df2 contains the further document links of aaa
df2 <- tibble(id_from=c(NA,"aaa","x","x"),
             id_to=c("aaa","x","x1","x2"),
             level=c(0,1,2,2))

df3 <- tibble(id_from=c(NA,"thank"),
                     id_to=c("thank","you"),
                     level=c(0,1))

#list with df
list <- list(df1)

#list with lookups
list_lookup <- list(df2,df3)

list_lookup
#> [[1]]
#> # A tibble: 4 × 3
#>   id_from id_to level
#>   <chr>   <chr> <dbl>
#> 1 <NA>    aaa       0
#> 2 aaa     x         1
#> 3 x       x1        2
#> 4 x       x2        2
#> 
#> [[2]]
#> # A tibble: 2 × 3
#>   id_from id_to level
#>   <chr>   <chr> <dbl>
#> 1 <NA>    thank     0
#> 2 thank   you       1

#what I need; an updated list of dfs where information from the lookup list are included

df1_wanted <- tibble(id_from=c(NA_character_,"111","222","333","444","444","aaa","bbb","x","x"),
                     id_to=c("111","222","333","444","aaa","bbb","x","ccc","x1","x1"),
                     level=c(0,1,2,3,4,4,5,5,6,6))

list(df1_wanted)
#> [[1]]
#> # A tibble: 10 × 3
#>    id_from id_to level
#>    <chr>   <chr> <dbl>
#>  1 <NA>    111       0
#>  2 111     222       1
#>  3 222     333       2
#>  4 333     444       3
#>  5 444     aaa       4
#>  6 444     bbb       4
#>  7 aaa     x         5  <- added from df2, level adjusted
#>  8 bbb     ccc       5  
#>  9 x       x1        6  <- added from df2, level adjusted
#> 10 x       x1        6  <- added from df2, level adjusted

Created on 2023-04-01 with reprex v2.0.2

Мой подход:

Я думал об использовании purrr::map для сопоставления функции с каждым элементом list, однако я не уверен, как эта функция должна выглядеть.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В этом решении:

  1. Сначала я определяю рекурсивную функцию get_tree(), которая принимает одну id и таблицу поиска и возвращает полное дерево из таблицы для этой id.
  2. Затем я определяю функцию complete_tree(), которая принимает фрейм данных и список таблиц поиска, перебирает get_tree() для каждого id_to, где search == 1 и для каждой таблицы поиска, корректирует level и привязывает результаты к исходному фрейму данных.
  3. Наконец, я перебираю complete_tree() для каждого элемента list.
library(dplyr)
library(purrr)

get_tree <- function(id, lookup) {
  branch <- filter(lookup, id_from == id)
  if (nrow(branch) == 0) return()
  bind_rows(
    branch, 
    map(branch$id_to, \(x) get_tree(x, lookup))
  )
}

complete_trees <- function(data, lookups) {
  branches <- pmap(
    filter(data, search == 1),
    \(id_to, level, ...) {
      bind_rows(map(
          lookups, 
          \(lookup) get_tree(id_to, lookup)
        )) %>%
        mutate(level = level + .env$level)
    }
  )
  bind_rows(data, branches) %>%
    select(!search) %>%
    arrange(level, id_from)
}

map(list, \(x) complete_trees(x, lookups = list_lookup))

Результат:

[[1]]
# A tibble: 10 × 3
   id_from id_to level
   <chr>   <chr> <dbl>
 1 <NA>    111       0
 2 111     222       1
 3 222     333       2
 4 333     444       3
 5 444     aaa       4
 6 444     bbb       4
 7 aaa     x         5
 8 bbb     ccc       5
 9 x       x1        6
10 x       x2        6

Спасибо, это чудесное решение. Я сейчас попытался вырезать ветки с похожим подходом, но снова застрял: stackoverflow.com/questions/75910943/…. Может у вас есть другая подсказка?

ava 02.04.2023 10:45

Другие вопросы по теме