tar_map处理tibble列表列丢失数据框类,如何解决?
问题描述
我使用tarchetypes::tar_map时遇到了问题:我的values_df是包含数值列index和数据框类型列表列df的tibble,但tar_map似乎丢失了df元素的数据框类,导致dplyr::slice()无法处理(slice不能操作列表)。以下是可复现代码:
targets::tar_dir({ # tar_dir() 在临时目录中运行代码 targets::tar_script({ library(dplyr) values_df = tibble(index = 1:3, df = list(mtcars)) list( tarchetypes::tar_map( values_df, names = "index", targets::tar_target(x, slice(df, index)) ) ) }) targets::tar_manifest() }) #> # A tibble: 3 × 2 #> name command #> <chr> <chr> #> 1 x_1 "slice(list(c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, \n 24.4, 22.8, … #> 2 x_2 "slice(list(c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, \n 24.4, 22.8, … #> 3 x_3 "slice(list(c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, \n 24.4, 22.8, …
从输出的command列能看到,df被转换成了list(c(...)),而非保留mtcars的数据框类型,运行时会触发slice()报错。
解决方案
问题根源是tar_map会将values_df中的具体数据对象直接展开为字面量代码,而非保留数据框的引用。可以通过两种方式解决:
方法1:将数据框作为独立Target引用
先定义生成数据框的Target,再在values_df中引用这个Target的名称,tar_map就能正确识别数据框类型:
targets::tar_dir({ targets::tar_script({ library(dplyr) list( # 先定义数据框的Target targets::tar_target(data_mtcars, mtcars), # 在values_df中引用Target名称 tarchetypes::tar_map( values = tibble(index = 1:3, df = list(data_mtcars)), names = "index", targets::tar_target(x, slice(df, index)) ) ) }) targets::tar_manifest() })
此时tar_manifest的command列会显示slice(data_mtcars, 1)这类正确代码,运行时不会丢失数据框类。
方法2:用引用方式保留数据框对象
如果不想单独定义Target,可以在values_df中用quote()保留数据框的引用,避免tar_map将其展开为字面量,再用!!解引用:
targets::tar_dir({ targets::tar_script({ library(dplyr) values_df = tibble(index = 1:3, df = list(quote(mtcars))) list( tarchetypes::tar_map( values_df, names = "index", targets::tar_target(x, slice(!!df, index)) ) ) }) targets::tar_manifest() })
这种方式能让slice正确识别并处理数据框。
内容的提问来源于stack exchange,提问作者mikeck
相关产品推荐
相关产品推荐

