如何将单个tibble的行迭代添加至tibble列表对应元素并循环匹配行数
解决方法:将单行元数据与列表中对应tibble绑定并循环填充
问题背景
现有一个包含3个tibble的列表ltb,每个tibble有10行数据:
library(dplyr) library(purrr) ltb <- list(tibble(a=1:10, b=1:10), tibble(a=1:10, b=1:10), tibble(a=1:10, b=1:10)) # 查看每个tibble的前2行 map(ltb, ~head(., 2))
输出:
[[1]] # A tibble: 2 × 2 a b <int> <int> 1 1 1 2 2 2 [[2]] # A tibble: 2 × 2 a b <int> <int> 1 1 1 2 2 2 [[3]] # A tibble: 2 × 2 a b <int> <int> 1 1 1 2 2 2
另有一个3行的tibbletib,每行对应ltb中一个元素的元数据:
tib <- tibble(data1 = letters[1:3], data2 = LETTERS[1:3], data3 = letters[1:3]) tib
输出:
# A tibble: 3 × 3 data1 data2 data3 <chr> <chr> <chr> 1 a A a 2 b B b 3 c C c
需求:将tib的第1行循环填充到ltb的第1个tibble的每一行,第2行填充到ltb的第2个tibble,以此类推,最终每个tibble新增对应元数据列。
解决方案
方法1:使用map2拆分元数据列表
核心思路是将tib拆分为单行tibble的列表,与ltb一一对应,再将每行元数据重复对应次数后与原tibble绑定:
# 将tib拆分为单行列表 tib_rows <- split(tib, seq(nrow(tib))) # 遍历绑定 newltb <- map2(ltb, tib_rows, function(tbl, row) { bind_cols(tbl, slice(row, rep(1, nrow(tbl)))) }) # 验证结果(查看每个tibble前3行) map(newltb, head, 3)
方法2:使用imap利用索引匹配
imap可以直接获取列表元素的索引,无需拆分元数据列表,更简洁:
newltb <- imap(ltb, function(tbl, idx) { # 根据索引取tib的对应行,重复对应次数后绑定 bind_cols(tbl, slice(tib, rep(idx, nrow(tbl)))) }) # 验证结果 map(newltb, head, 3)
两种方法都会得到预期结果:
[[1]] # A tibble: 3 × 5 a b data1 data2 data3 <int> <int> <chr> <chr> <chr> 1 1 1 a A a 2 2 2 a A a 3 3 3 a A a [[2]] # A tibble: 3 × 5 a b data1 data2 data3 <int> <int> <chr> <chr> <chr> 1 1 1 b B b 2 2 2 b B b 3 3 3 b B b [[3]] # A tibble: 3 × 5 a b data1 data2 data3 <int> <int> <chr> <chr> <chr> 1 1 1 c C c 2 2 2 c C c 3 3 3 c C c
内容的提问来源于stack exchange,提问作者Tea Tree
相关产品推荐
相关产品推荐

