R语言如何通过for循环批量创建并赋值多个变量?
前置修正
你定义的my_list存在重复命名问题,三个列表元素均使用sample_1作为名称,会导致后续遍历出错,需先修正为对应样本编号:
my_list = list( sample_1 = read.table(file = "S01.tsv", sep = "\t", header = F), sample_2 = read.table(file = "S02.tsv", sep = "\t", header = F), sample_3 = read.table(file = "S03.tsv", sep = "\t", header = F) # 其余样本按相同规则补充即可 )
另外注意:读入数据时设置了header = F,默认列名为V1、V2……,需提前确认存储基因类型的列名是否为gene_type,若不是请先通过colnames()为数据框设置正确列名,否则后续过滤会报错。
方案1:完全匹配需求的for循环实现
使用assign()函数动态拼接变量名并赋值到全局环境,运行后即可直接得到你需要的所有独立变量:
# 替换为你的全部基因名称向量 genes = c("gene1", "gene2", "gene3") # 双层循环遍历所有「样本×基因」组合 for (sample_name in names(my_list)) { current_sample_data = my_list[[sample_name]] for (target_gene in genes) { # 按照要求的格式拼接变量名 output_var_name = paste0(target_gene, "_row_quantity_", sample_name) # 计算匹配行数并赋值到全局环境 assign( x = output_var_name, value = current_sample_data %>% dplyr::filter(grepl(target_gene, gene_type)) %>% nrow(), envir = .GlobalEnv ) } }
运行完成后,环境中会直接生成gene1_row_quantity_sample1、gene2_row_quantity_sample1……所有对应变量,直接调用即可获取统计值。
匹配提示:如果你的基因名存在包含关系(比如同时存在
gene1和gene11),普通grepl()会出现误匹配,可将匹配规则改为grepl(paste0("^", target_gene, "$"), gene_type)实现精确匹配。
方案2:结构化存储结果(R语言最佳实践,推荐)
不建议在全局环境中生成大量零散独立变量,后续批量处理、检索时极易出错,更推荐将结果存储在结构化对象中:
- 命名列表存储:调用方式和独立变量几乎无差别,且便于统一管理
gene_count_result = list() for (sample_name in names(my_list)) { current_sample_data = my_list[[sample_name]] for (target_gene in genes) { output_var_name = paste0(target_gene, "_row_quantity_", sample_name) gene_count_result[[output_var_name]] = current_sample_data %>% dplyr::filter(grepl(target_gene, gene_type)) %>% nrow() } } # 调用示例:gene_count_result$gene1_row_quantity_sample1 即可获取对应统计值
- 汇总数据框存储:适合后续做统计、可视化
# 生成所有基因和样本的组合 gene_count_df = expand.grid(gene = genes, sample = names(my_list), stringsAsFactors = F) # 批量计算所有组合的行数 gene_count_df$row_count = mapply(function(g, s) { my_list[[s]] %>% dplyr::filter(grepl(g, gene_type)) %>% nrow() }, gene_count_df$gene, gene_count_df$sample)
内容的提问来源于stack exchange,提问作者Valentin
相关产品推荐
相关产品推荐

