使用purrr::map为data.table列表批量添加新列的技术问询
给列表中每个data.table批量添加对应新列的方法
首先先回顾下你的场景,你已经创建了这样的data.table列表:
library(data.table) dt1 <- data.table(x=1:3,y=(1:3)^2) dt2 <- data.table(x=5:7,y=(1:3)^2) ldt <- list(d1=dt1,d2=dt2) new_col <- c("DOC1","DOC2")
你的需求很明确:给ldt里的d1和d2分别添加z列,其中d1的z列全为"DOC1",d2的z列全为"DOC2"。这里给你几种实用的解决方法:
方法一:基础R循环(直观易懂)
这是最容易理解的方式,利用索引一一对应列表元素和new_col的值,借助data.table的引用修改特性直接添加列:
for (i in seq_along(ldt)) { # 给第i个data.table添加z列,赋值为new_col的第i个元素 ldt[[i]][, z := new_col[i]] }
因为data.table是引用修改,所以这个循环不需要重新给ldt赋值,循环结束后原列表就已经更新好了。
方法二:用purrr包的map2函数(函数式编程风格)
如果你习惯函数式编程,purrr的map2可以很简洁地完成配对操作:
library(purrr) # 配对每个data.table和对应的new_col值,添加z列后返回新列表 ldt <- map2(ldt, new_col, ~ .x[, z := .y])
这里.x代表ldt中的每个data.table,.y代表new_col中对应的元素,一行代码就能完成批量操作。
方法三:基础R的mapply函数(无需额外包)
如果不想加载额外的包,基础R的mapply也能实现同样的效果:
# 配对处理每个dt和对应值,SIMPLIFY=FALSE确保返回列表格式 ldt <- mapply(function(dt, val) dt[, z := val], ldt, new_col, SIMPLIFY = FALSE)
这几种方法都能满足你的需求,你可以根据自己的编码习惯选择~
内容的提问来源于stack exchange,提问作者Lazarus Thurston
相关产品推荐
相关产品推荐

