我有以下工作代码:
test_hierarchie <- tribble(~child, ~parent,
"A", "B",
"B", "C",
"D", "E"
)
test_hierarchie_transformed <- test_hierarchie %>%
left_join(test_hierarchie, by = c("parent" = "child"), suffix = c("", "_grant")) %>%
left_join(test_hierarchie, by = c("parent_grant" = "child"), suffix = c("", "_grant")) %>%
left_join(test_hierarchie, by = c("parent_grant_grant" = "child"), suffix = c("", "_grant")) %>%
left_join(test_hierarchie, by = c("parent_grant_grant_grant" = "child"), suffix = c("", "_grant")) %>%
left_join(test_hierarchie, by = c("parent_grant_grant_grant_grant" = "child"), suffix = c("", "_grant")) %>%
pivot_longer(names_to = "relation", cols = contains("parent"), values_to = "parent") %>%
filter(!is.na(parent))
Run Code Online (Sandbox Code Playgroud)
结果:
# A tibble: 4 x 3
child relation parent
<chr> <chr> <chr>
1 A parent B
2 A parent_grant C
3 B parent C
4 D parent E
Run Code Online (Sandbox Code Playgroud)
这是期望的结果,存在大量的 left_join,因为我对于真实数据不确定最大层次结构是什么。
我的问题是:有没有办法做到更简洁、更有活力?谢谢!
编辑 1:是的,我的意思是“盛大”而不是“授予”,哈哈 编辑 2:很好的解决方案,正是我正在寻找的!感谢大家的参与,前几天我正在考虑另一个项目,iGraph 似乎对此非常有帮助。
按照 @zx8754 的建议,实现所需结果的一种选择是left_joins通过递归函数执行此操作,该函数在没有更多匹配项时停止:
library(dplyr)\nlibrary(tidyr)\n\ntest_hierarchie <- tribble(\n ~child, ~parent,\n "A", "B",\n "B", "C",\n "D", "E"\n)\n\nleft_join_recursive <- function(x, by) {\n x <- left_join(x, test_hierarchie, by = setNames("child", by), suffix = c("", "_grant"))\n byby <- paste0(by, "_grant")\n if (!all(is.na(x[[byby]]))) {\n left_join_recursive(x, byby) \n } else {\n x\n }\n}\n\ntest_hierarchie_transformed <- left_join_recursive(test_hierarchie, "parent") %>%\n pivot_longer(names_to = "relation", cols = contains("parent"), values_to = "parent") %>%\n filter(!is.na(parent))\n\ntest_hierarchie_transformed\n#> # A tibble: 4 \xc3\x97 3\n#> child relation parent\n#> <chr> <chr> <chr> \n#> 1 A parent B \n#> 2 A parent_grant C \n#> 3 B parent C \n#> 4 D parent E\nRun Code Online (Sandbox Code Playgroud)\n为了检查该方法是否适用于更一般的情况,我在示例数据中添加了另一行:
\ntest_hierarchie <- add_row(test_hierarchie, child = "C", parent = "D")\n\ntest_hierarchie_transformed <- left_join_recursive(test_hierarchie, "parent") %>%\n pivot_longer(names_to = "relation", cols = contains("parent"), values_to = "parent") %>%\n filter(!is.na(parent))\n\ntest_hierarchie_transformed\n#> # A tibble: 10 \xc3\x97 3\n#> child relation parent\n#> <chr> <chr> <chr> \n#> 1 A parent B \n#> 2 A parent_grant C \n#> 3 A parent_grant_grant D \n#> 4 A parent_grant_grant_grant E \n#> 5 B parent C \n#> 6 B parent_grant D \n#> 7 B parent_grant_grant E \n#> 8 D parent E \n#> 9 C parent D \n#> 10 C parent_grant E\nRun Code Online (Sandbox Code Playgroud)\n