R语言循环中创建名称动态变化对象的方法求助
在R循环中创建名称可变的对象解决方案
核心问题
你需要在循环中生成名称随变量(如年份、序号)变化的对象,比如obj_17、dise2021、a1这类,但直接用字符串赋值会报错。下面分基础场景和复杂survey统计场景给出解决方案,优先推荐R的最佳实践(用列表存储),同时提供直接创建全局对象的方法。
基础场景:批量创建简单对象
你的错误代码分析
你之前生成对象名称字符串的代码(如paste0("a",i-16)、sprintf("obj_%s",i))是正确的,但直接用字符串作为赋值左侧是无效的:
anio=17:21 for (i in anio) { sprintf("obj_%s",i)=i-17 # 错误:左侧不能是字符串表达式 }
正确实现方式
方式1:推荐用列表存储(最佳实践)
避免在全局环境中生成大量零散对象,用列表统一管理更便于后续操作(比如批量遍历、修改):
anio=17:21 obj_list <- list() for (i in anio) { obj_name <- sprintf("obj_%s", i) obj_list[[obj_name]] <- i - 17 } # 调用对象:obj_list$obj_17 或 obj_list[["obj_17"]]
方式2:用assign()创建全局对象
如果一定要在全局环境生成独立命名的对象,使用assign()函数:
anio=17:21 for (i in anio) { obj_name <- sprintf("obj_%s", i) assign(obj_name, i - 17) } # 直接调用:obj_17、obj_18等
复杂场景:批量处理survey设计与统计
针对你提到的生成dise2021、esi2021、a1这类对象的需求,同样优先用列表管理:
假设前提
你已经有按年份命名的原始数据框:esi2017、esi2018、esi2019、esi2020、esi2021
批量生成survey设计对象(diseXXXX)
anio=17:21 # 存储survey设计的列表 dise_list <- list() options(survey.lonely.psu="remove") for (i in anio) { # 获取对应年份的esi数据框 esi_df <- get(sprintf("esi%s", i)) # 生成survey设计 dise_obj <- esi_df %>% as_survey_design(ids = id_directorio, strata = estrato, weights = fact_cal_esi) # 存入列表,名称为diseXXXX dise_list[[sprintf("dise%s", i)]] <- dise_obj } # 调用:dise_list$dise2021
批量生成统计结果对象(a1到a5)
基于上面的survey设计列表,批量生成a1(对应2017)到a5(对应2021)的统计结果:
# 存储统计结果的列表 a_list <- list() for (idx in seq_along(anio)) { # 获取对应年份的survey设计 dise_obj <- dise_list[[idx]] # 生成统计结果 a_obj <- dise_obj %>% filter(ocup_ref==1) %>% summarise(ing_medio = survey_mean(ing_t_p, vartype="cv", na.rm=T)) # 存入列表,名称为a1、a2... a_list[[sprintf("a%s", idx)]] <- a_obj } # 调用:a_list$a1 或 a_list$a5
如果要生成全局对象
如果需要把survey设计或统计结果直接放到全局环境,用assign()替代列表存储:
# 批量生成全局的diseXXXX对象 for (i in anio) { esi_df <- get(sprintf("esi%s", i)) dise_obj <- esi_df %>% as_survey_design(ids = id_directorio, strata = estrato, weights = fact_cal_esi) assign(sprintf("dise%s", i), dise_obj) } # 批量生成全局的a1到a5对象 for (idx in seq_along(anio)) { dise_obj <- get(sprintf("dise%s", anio[idx])) a_obj <- dise_obj %>% filter(ocup_ref==1) %>% summarise(ing_medio = survey_mean(ing_t_p, vartype="cv", na.rm=T)) assign(sprintf("a%s", idx), a_obj) }
内容的提问来源于stack exchange,提问作者Sebastián Valladares
相关产品推荐
相关产品推荐

