在R中通过变量名批量修改带前缀对象的slot属性
解决方法
你原来用assign(paste0('obj_num', it, '@slot1'), 'modified')的写法行不通,因为assign的第一个参数必须是完整的对象名,不能直接把槽访问符@拼进去。要修改对象的槽,得先把对象取出来,修改完再存回去。
基础情况:修改S4对象的单个槽
针对你给出的myclass示例,正确的循环写法如下:
setClass("myclass", representation = representation( slot1="character" )) obj_num1 <- new('myclass', slot1='original') obj_num2 <- new('myclass', slot1='original') obj_num3 <- new('myclass', slot1='original') # 循环修改slot1 for(it in 1:3){ # 1. 获取当前对象 current_obj <- get(paste0('obj_num', it)) # 2. 修改slot1 current_obj@slot1 <- 'modified' # 3. 把修改后的对象存回原名称 assign(paste0('obj_num', it), current_obj) } # 验证结果 obj_num1@slot1 # 输出 "modified"
进阶情况:槽是数据框/矩阵时修改单列
如果你的槽是数据框(或矩阵),想修改其中某一列,只需要在第二步针对槽内的元素操作即可,比如:
# 定义带数据框槽的类 setClass("myclass_df", representation = representation( slot1="data.frame" )) # 创建示例对象 obj_num1 <- new('myclass_df', slot1=data.frame(col1=1:5, col2=rep('original',5))) obj_num2 <- new('myclass_df', slot1=data.frame(col1=1:5, col2=rep('original',5))) obj_num3 <- new('myclass_df', slot1=data.frame(col1=1:5, col2=rep('original',5))) # 循环修改slot1里的col2列 for(it in 1:3){ current_obj <- get(paste0('obj_num', it)) # 修改数据框的col2列 current_obj@slot1$col2 <- rep('modified',5) # 或者用索引:current_obj@slot1[, 'col2'] <- rep('modified',5) assign(paste0('obj_num', it), current_obj) } # 验证结果 obj_num1@slot1$col2 # 输出五个"modified"
额外建议:用列表管理对象更省心
其实不建议把多个同类型对象散落在全局环境里,最好把它们放进一个列表里,操作起来更简洁,也不容易出错:
# 把对象放进列表 obj_list <- list( obj_num1 = new('myclass', slot1='original'), obj_num2 = new('myclass', slot1='original'), obj_num3 = new('myclass', slot1='original') ) # 批量修改槽 obj_list <- lapply(obj_list, function(x){ x@slot1 <- 'modified' x }) # 要单独取某个对象直接用obj_list$obj_num1 obj_list$obj_num1@slot1
内容的提问来源于stack exchange,提问作者M.G.
相关产品推荐
相关产品推荐

