R语言中将lapply语法改写为嵌套for循环的问题求助
R嵌套for循环改写列表过滤函数
我需要将现有基于foreach并行实现的R列表过滤函数,改写为纯嵌套for循环的实现形式。
测试用嵌套列表
x <- list(one = list(one_1 = list(seq = c(rep(1,5), rep(2,4)), start = -1, end = 5), one_2 = list(seq = c(rep(2,5), rep(1,5), rep(3,4), rep(2,11)), start = 2, end = 6), one_3 = list( seq = c(rep(3,4), rep(1,12), rep(4,6)), start = -3, end = 7)), two = list(two_1 = list( seq = c(rep(1,7), rep(2,4), rep(1,3)), start = 8, end = 222), two_2 = list(seq = c(rep(4,4), rep(1,3), rep(2,6)), start = -1, end = 54)))
原有可正常运行的foreach版本
first <- function(input_list, value){ filtered_input <- foreach::foreach(i = seq_along(input_list)) %dopar% { filtered_output <- Filter(function(x) any(with(rle(x$seq), lengths[values==value]>=4)) & x$start>=0, input_list[[i]]) lapply(filtered_output, function(x) x) } }
调用命令:
y <- first(input_list = x, value = 2)
运行后得到的预期输出结构如下:
desired_y <- list(list(one_2 = list(seq = c(2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), start = 2, end = 6)), list(two_1 = list(seq = c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1), start = 8, end = 222)))
自行编写的错误版本
自行尝试编写的嵌套for循环版本无法正常运行,代码如下:
second <- function(input_list, value){ for (x in seq_along(input_list)){ for (y in seq_along(input_list[[x]])){ filtered_input <- c(filtered_input, foreach::foreach(y) %dopar% filtered_output <- Filter(function(z) any(with(rle(z$seq), lengths[values==value]>=4)) & z$start>=0, input_list[[x]])) } } return(filtered_input) } y <- second(input_list = x, value = 2)
该版本存在三个核心问题:
- 未提前初始化结果变量
filtered_input,首次循环拼接时会触发对象不存在的报错 - 错误混用
for循环和foreach逻辑,未对单个子项做条件判断,重复对整层列表执行过滤导致结果重复 - 未保留原列表的两层嵌套结构,直接拼接会导致输出扁平化,和预期结构不符
正确嵌套for循环实现
second <- function(input_list, value){ # 初始化和输入第一层长度一致的结果列表 filtered_input <- vector("list", length(input_list)) # 外层循环遍历第一层列表 for (i in seq_along(input_list)) { matched <- list() # 内层循环遍历当前第一层下的所有第二层子项 for (j in seq_along(input_list[[i]])) { item <- input_list[[i]][[j]] # 复用原过滤条件:目标值连续出现长度>=4 且 start>=0 rle_res <- rle(item$seq) match_condition <- any(rle_res$lengths[rle_res$values == value] >= 4) && item$start >= 0 if (match_condition) { # 保留原子项名称存入匹配结果 matched[[names(input_list[[i]])[j]]] <- item } } filtered_input[[i]] <- matched } return(filtered_input) } # 测试调用 y <- second(input_list = x, value = 2)
运行上述代码得到的结果和原first函数输出、desired_y完全一致。
内容的提问来源于stack exchange,提问作者ramen
相关产品推荐
相关产品推荐

