如果其他人遇到这个问题,想要一个更完整的解决方案,这是我在工作流程中使用 purrr 包解决类似问题的方法。
这是我的示例数据:
df <- data.frame(name = c("bob", "bob", "joe", "joe"),
target = c("yellow", "red", "yellow", "red"),
method = c("fly", "jump", "walk", "run"),
after = c("lunch", "breakfast", "dinner", "breakfast"),
stringsAsFactors = F)
这与OP提供的相似,但包含了额外的一级。
以下是我构建YAML文件的方法:
library(purrr)
library(dplyr)
nested_lists <- df %>%
split(f = .$name) %>%
purrr::map(dplyr::select, -name) %>%
purrr::map(~ split(.x, f = .x$target)) %>%
purrr::map_depth(2, dplyr::select, -target) %>%
list(samples = .)
这个名为nested_lists
的对象可以使用yaml::write_yaml
写入文件,或者使用as.yaml
打印到屏幕上:
> cat(yaml::as.yaml(nested_lists))
samples:
bob:
red:
method: jump
after: breakfast
yellow:
method: fly
after: lunch
joe:
red:
method: run
after: breakfast
yellow:
method: walk
after: dinner
这是一种很好的方法,它可以很好地概括任意层级。
例如,如果我们用purrr::map_depth(1, ...)
替换purrr::map(...)
调用,并将嵌套列表扩展到另一个级别,模式变得更加清晰:
library(purrr)
library(dplyr)
nested_lists3 <- df %>%
split(f = .$name) %>%
purrr::map_depth(1, dplyr::select, -name) %>%
purrr::map_depth(1, ~ split(.x, f = .x$target)) %>%
purrr::map_depth(2, dplyr::select, -target) %>%
purrr::map_depth(2, ~ split(.x, f = .x$method)) %>%
purrr::map_depth(3, dplyr::select, -method) %>%
list(samples = .)
cat(yaml::as.yaml(nested_lists3))
输出:
samples:
bob:
red:
jump:
after: breakfast
yellow:
fly:
after: lunch
joe:
red:
run:
after: breakfast
yellow:
walk:
after: dinner