R语言list与as.list处理data.table报subscript out of bounds错
R场景下
list()与as.list()的区别及报错原因 两个函数的本质差异
list()是列表构造函数:传入的参数会原封不动成为新列表的元素,不会做额外的转换或解析。传入d1、d2两个data.table对象时,生成的列表两个元素就分别是完整的d1、d2数据集本身。as.list()是类型转换函数:仅负责将传入的R对象按照对应类型的转换规则强制转成列表格式,不会自动解析字符串对应的环境变量。
报错的核心原因
第二段代码触发错误和as.list()本身的逻辑无关,根源是传入as.list()的对象不符合预期:
ls()函数的返回值是匹配到的对象名称组成的字符向量,不是对象本身。示例中ls(pattern= "^d1$|^d2$", all.names = TRUE)的运行结果就是长度为2的字符向量c("d1", "d2"),里面存的是两个对象的名字字符串,不是data.table数据。- 对这个字符向量执行
as.list(),只是把长度为2的字符向量拆成了两个长度为1的字符串元素,最终得到的列表结构是:[[1]] [1] "d1" [[2]] [1] "d2" - 后续
lapply遍历时,每次拿到的i是单元素字符串,不是data.table。对长度为1的字符串执行i[[2]]取第二个元素,自然会触发下标越界错误。
而直接用list(d1,d2)生成的列表,每个元素都是完整的data.table结构,每个数据集都有2列,取第二列计算NA数量自然能正常运行,返回两个0的结果。
按对象名批量获取对象生成列表的正确方法
如果要通过ls()匹配到的对象名批量获取环境中的数据集,不要直接对ls()的结果用as.list(),用mget()即可,它会把字符向量里的每个字符串解析成对应环境里的对象,最终生成的列表和直接list(d1,d2)结构完全一致:
dt_ls <- mget(ls(pattern= "^d1$|^d2$", all.names = TRUE)) lapply(dt_ls, function(i) sum(is.na(i[[2]])))
内容的提问来源于stack exchange,提问作者rane
相关产品推荐
相关产品推荐

