tidyr::crossing()处理列表型tibble时行数异常减少的技术问询
tidyr::crossing()处理列表类型列时的行为说明 问题现象
当使用tidyr::crossing()交叉两个tibble时,若其中一个tibble的列是包含相同内容的列表类型,交叉结果会只保留1行,而非预期的2行。但原子类型列的交叉则符合笛卡尔积的预期:
- 1行tibble(df1)和2行原子类型列tibble(df2)交叉,得到2行结果,符合预期;
- 1行tibble(df1)和2行列表列tibble(df3,两个列表元素是内容完全相同的
tibble(y=2))交叉,结果仅1行。
原因解析
crossing()默认会对输入的所有列执行去重操作(等价于设置.distinct = TRUE)。对于列表类型的元素,crossing()会判断列表中的每个元素是否完全相等——由于df3里的两个列表元素是内容完全一致的tibble,被判定为重复值,因此交叉后只保留了唯一的组合。
如果修改df3,让两个列表元素存在差异,交叉结果就会是预期的2行:
df3_mod <- tibble(y=list(tibble(y=2), tibble(y=3))) crossing(df1, df3_mod) #> # A tibble: 2 × 2 #> x y #> <dbl> <list> #> 1 1 <tibble [1 × 1]> #> 2 1 <tibble [1 × 1]>
解决方案
如果需要保留所有笛卡尔积组合,不管是否存在重复值,可以显式设置.distinct = FALSE参数:
crossing(df1, df3, .distinct = FALSE) #> # A tibble: 2 × 2 #> x y #> <dbl> <list> #> 1 1 <tibble [1 × 1]> #> 2 1 <tibble [1 × 1]>
这样就能得到预期的2行结果。
内容的提问来源于stack exchange,提问作者mpettis
相关产品推荐
相关产品推荐

