R中嵌套列表的正确填充与子元素访问:解决下标越界问题
R嵌套列表下标越界问题及解决方案
一、下标越界错误的原因
直接执行第一种赋值代码触发subscript out of bounds,核心原因是R无法自动逐层创建嵌套列表的空层级:
- 当尝试给
mylist[['ALPHA']][[1]][['id1']]赋值时,mylist[['ALPHA']]本身不存在,更没有[[1]]这个子列表,R无法凭空生成多层嵌套的空结构。 - 第二种写法能正常运行,是因为赋值顺序是从外层到内层的元素追加:先创建
mylist[['ALPHA']]空列表,再创建['id1']子列表,最后给这个子列表的[[1]]位置赋值——R支持给已有列表动态追加元素,因此不会报错。
修复第一种结构的赋值代码
要使用你偏好的结构,需提前初始化对应层级,比如先创建ALPHA下的两个空列表:
mylist <- list() # 先初始化ALPHA层级下的两个空列表 mylist[['ALPHA']] <- list(list(), list()) # 现在可正常赋值 mylist[['ALPHA']][[1]][['id1']] = 46 mylist[['ALPHA']][[2]][['id1']] = 28 mylist[['ALPHA']][[1]][['id2']] = 87 mylist[['ALPHA']][[2]][['id2']] = 12
此时mylist[['ALPHA']][[1]]和[[2]]已是存在的空列表,直接给子元素赋值不会触发下标越界错误。
二、第二种结构转换为目标格式的方法
如果只能使用第二种结构,要获取对应位置的所有id列表,可参考以下方法:
假设第二种结构的列表已创建完成:
mylist <- list() mylist[['ALPHA']][['id1']][[1]]=46 mylist[['ALPHA']][['id1']][[2]]=28 mylist[['ALPHA']][['id2']][[1]]=87 mylist[['ALPHA']][['id2']][[2]]=12
获取所有id的第1个元素组成的列表
用基础R的lapply:
mylist1 <- lapply(mylist[['ALPHA']], function(x) x[[1]])
或用purrr包简化代码:
library(purrr) mylist1 <- map(mylist[['ALPHA']], 1)
得到的mylist1结构为list(id1=46, id2=87),和第一种结构的mylist[['ALPHA']][[1]]完全一致。
获取所有id的第2个元素组成的列表
同理操作:
# 基础R方法 mylist2 <- lapply(mylist[['ALPHA']], function(x) x[[2]]) # purrr方法 mylist2 <- map(mylist[['ALPHA']], 2)
修正之前的sapply用法
你之前用sapply得到多层嵌套,是因为sapply默认会简化结果为向量/矩阵,只需添加simplify=FALSE参数就能保持列表结构:
mylist2 <- sapply(mylist[['ALPHA']], "[", 2, simplify=FALSE)
内容的提问来源于stack exchange,提问作者DaniCee
相关产品推荐
相关产品推荐

