使用qs保存并加载的data.table是否为合规的data.table对象
问题解答
加载得到的data.table是否合规
qs反序列化得到的是完全合规的data.table对象,调用is.data.table(dt_saved)会返回TRUE,所有data.table语法均可正常执行。
该异常行为的本质原因是:
- 原生创建的data.table列名属性为内部共享引用的字符串向量,
colnames()返回的是指向该内部向量的指针,修改列结构时指针指向的内容会同步更新 - qs反序列化过程只会还原对象的数值与属性值,不会主动触发data.table的内部引用绑定机制。刚加载完成的对象内部列名还处于普通值状态,第一次修改列操作时data.table会自动完成内部引用初始化,因此第二次及之后的操作就恢复了指针同步行为。
解决方案
提供两种可落地的处理方案:
方案1:加载后主动激活内部引用(推荐)
加载qs文件后主动调用setDT(dt_saved),即可立即完成内部引用绑定,恢复原生data.table的所有特性:
dt_saved <- qs::qread("dt_saved.qs") setDT(dt_saved) # 主动激活内部引用机制 # 后续操作和原生data.table完全一致 cnames <- colnames(dt_saved) dt_saved[, new_col_1 := 1] print(cnames) # 会同步返回包含new_col_1的最新列名
也可以通过truelength(dt_saved)验证激活效果:刚加载完成时返回值为0,调用setDT后返回值和原生创建的data.table一致。
方案2:业务逻辑规避
如果无法确保所有加载场景都做激活处理,建议业务代码中不要长期存储colnames(dt)的返回值,每次需要使用列名时直接调用colnames(dt)获取最新值,从逻辑上彻底规避列名不同步的问题。
内容的提问来源于stack exchange,提问作者alexp
相关产品推荐
相关产品推荐

