R中data.table赋值后原列表samples自动变更的原因咨询
问题原因解析
第一个场景:修改同步到原列表的原因
当你执行 sa = samples[[id]] 时,sa并没有复制出一个新的data.table,它只是指向了内存中samples[[id]]对应的那个data.table对象——这是data.table默认的引用传递机制,目的是提升性能,避免不必要的内存复制。
而sa[, type := sample(sa$type)]是data.table专属的原地修改语法(:=操作符),它会直接在当前指向的data.table对象上修改数据,不会创建副本。所以你修改的其实就是samples[[id]]本身,自然原列表里的内容会跟着变。
第二个场景:原列表未变更的原因
当你先执行sa$type = sample(sa$type)时,这个操作触发了R的*复制-on-modify(修改时复制)*机制:
$<-是基础R的赋值操作,它不识别data.table的引用语义,当你用它修改data.table的列时,R会自动复制出一个全新的data.table对象赋值给sa,此时sa和samples[[id]]就不再指向同一个内存对象了。- 之后再执行
sa[, type := sample(sa$type)],修改的只是这个新复制出来的sa对象,和原列表里的samples[[id]]毫无关系,所以原列表不会有变化。
实用建议
如果想一开始就复制出独立的data.table,彻底避免引用关联问题,直接使用data.table提供的显式复制函数:
sa = copy(samples[[id]])
内容的提问来源于stack exchange,提问作者misakarenako
相关产品推荐
相关产品推荐

