如何用dplyr在R中实现嵌套tibble列表间的逐列除法?
解决嵌套Tibble的逐列比值计算问题
你的报错原因很明确:直接用tibble2 / tibble1时,R会把这两个当成整个数据框的列(列表类型),而不是逐个访问每个AccountNumber对应的嵌套小tibble,自然会抛出"非数值参数"的错误。
想要优雅地在嵌套结构内完成计算,我们可以用purrr包的map2函数——它专门用来对两个长度相同的列表进行逐元素配对运算,完美适配你的场景。
完整解决方案代码
library(tidyverse) # 先生成你提供的嵌套tibble tibble1 <- tibble(AccountNumber = 1:3, A_1 = 1, B_1 = 2, C_1 = 3) %>% group_by(AccountNumber) %>% nest(.key = "Tibble1") tibble2 <- tibble(AccountNumber = 1:3, A_2 = 4, B_2 = 5, C_2 = 6) %>% group_by(AccountNumber) %>% nest(.key = "Tibble2") tibble_joined <- left_join(tibble1, tibble2, by = "AccountNumber") # 生成Tibble3:逐列计算Tibble2/Tibble1的比值 tibble_result <- tibble_joined %>% mutate(Tibble3 = map2(Tibble2, Tibble1, ~ .x / .y))
代码解释
map2(Tibble2, Tibble1, ~ .x / .y):遍历每一行的Tibble2和Tibble1元素(每个都是1行3列的小tibble),对这两个小tibble执行逐列除法。因为两个小tibble的行列结构完全一致,R会自动按位置对应计算。- 这种方法全程保持嵌套结构,不需要展开数据框,即使你的列数再多(比如几十上百列),代码也不用修改,非常高效。
可选:自定义Tibble3的列名
如果想把Tibble3的列名改成更直观的格式(比如把A_2改成A_ratio),可以在map2里加一步列名替换:
tibble_result <- tibble_joined %>% mutate(Tibble3 = map2(Tibble2, Tibble1, ~ { ratio_tbl <- .x / .y # 把列名里的"_2"替换成"_ratio" colnames(ratio_tbl) <- str_replace(colnames(ratio_tbl), "_2", "_ratio") ratio_tbl }))
验证结果
查看第一个AccountNumber对应的Tibble3:
tibble_result$Tibble3[[1]] #> # A tibble: 1 × 3 #> A_ratio B_ratio C_ratio #> <dbl> <dbl> <dbl> #> 1 4 2.5 2
完全符合预期的逐列比值结果。
内容的提问来源于stack exchange,提问作者clarkjoe
相关产品推荐
相关产品推荐

