使用ifelse为变量赋值data.table时结果异常的原因咨询
为什么
ifelse没法完整返回data.table? 哈哈,这个坑我之前踩过!其实核心是ifelse()和普通if()的设计定位完全不同,咱们一步步理清楚:
1. ifelse是「元素级向量化工具」,不是「对象级工具」
ifelse的初衷是对单个元素做条件判断和返回,它会把复杂对象(比如data.table)拆成最基础的单元来处理。而data.table本质上是带特殊属性的列表(每一列就是列表的一个元素),当你把DT1传给ifelse时,它会把DT1当成列表来遍历——因为你的条件n>0是长度为1的标量,它会把这个条件循环匹配到每一列,最后把每一列的结果打包成新列表返回。这就是为啥你拿到的DT2是列表,而且看起来只保留了DT1的列内容(其实是所有列组成的列表,只是打印方式容易让人误解)。
你可以跑个代码验证下:
str(ifelse(n>0, DT1, NA))
输出会显示这是一个长度等于DT1列数的列表,每个元素对应DT1的一列,完全不是完整的data.table对象。
2. 用if()才能完整保留data.table结构
普通if()是「标量条件判断工具」,它不会拆解输入的对象结构,只会根据条件真假直接返回整个对象。当你用if(n>0) DT1 else NA时,因为n>0是TRUE,它就原封不动把整个DT1返回,自然保留了所有行列和data.table的属性。
小补充
如果是要对data.table的行/列元素做向量化的条件赋值(比如给某列的部分元素替换值),那ifelse或者data.table专属的fifelse是合适的;但如果是根据一个标量条件返回整个data.table对象,那if()才是正确选择。
内容的提问来源于stack exchange,提问作者Christian B.
相关产品推荐
相关产品推荐

