我正在努力提高我在R中的一个脚本的速度,其中一个需要很长时间的部分是在某些条件下清理列表。 可能没有必要完全理解我想做什么,并直接转到我需要改进的代码。
所以这就是事情: 我有一个列表,列表的每个元素都是2个元素的列表: - 第一个元素是整数向量,长度在1到4之间 - 第二个元素是长度为6的布尔矢量
这是创建这样一个列表(1000个元素)的代码:
numberList<-1000
l.gen<-lapply(1:numberList,function(i){
return(list(var = floor(runif(floor(runif(1,1,5)),1,7)),vec = as.logical(floor(runif(6,0,1.99)))))
})
看起来像那样:
> l.gen
[[1]]
[[1]]$var
[1] 1 4 2
[[1]]$vec
[1] FALSE FALSE FALSE FALSE TRUE TRUE
[[2]]
[[2]]$var
[1] 3
[[2]]$vec
[1] FALSE FALSE FALSE TRUE TRUE FALSE
[[3]]
[[3]]$var
[1] 6
[[3]]$vec
[1] TRUE FALSE TRUE FALSE TRUE TRUE
[[4]]
[[4]]$var
[1] 6
[[4]]$vec
[1] TRUE TRUE TRUE FALSE FALSE FALSE
现在清洁部分, 我想从此列表中删除满足两个条件的所有元素“l”: 元素“l”的“$ vec”与列表中的另一个元素共有3次TRUE:
例如:
$vec
[1] TRUE TRUE FALSE TRUE TRUE FALSE
和
$vec
[1] TRUE FALSE FALSE TRUE TRUE FALSE
共有3个TRUE(第1个,第4个和第5个位置),所以它与条件不匹配。
如果我们有第一个条件,则测试第二个条件: 元素的$ var应该至少有一个共同的元素(与它们各自的位置无关)
所以
[[1]]$var
[1] 1 4 2
和
[[1]]$var
[1] 3 1
满足该条件(因为“1”在两个向量中)
如果列表中的两个元素满足这两个条件,我会删除带有较短$ var
的元素例如:
[[3]]
[[3]]$var
[1] 6
[[3]]$vec
[1] TRUE FALSE TRUE FALSE TRUE TRUE
[[3]]
[[3]]$var
[1] 6 3 5
[[3]]$vec
[1] TRUE TRUE TRUE FALSE TRUE TRUE
应删除此元素:
[[3]]
[[3]]$var
[1] 6
[[3]]$vec
[1] TRUE FALSE TRUE FALSE TRUE TRUE
所以这是我尝试过的符合我要求的代码:
res<-lapply(l.gen,function(l){
for (i in 1:length(l)){
if (length(l$var)<length(l.gen[[i]]$var)){
in.common<-sum(l$vec&l.gen[[i]]$vec)
if(in.common>limit){
var.in.common<-sum(l$var%in%l.gen[[i]]$var)
if(var.in.common>0){
return(NULL)
} else {
return("OK")
}
} else {
return("OK")
}
}
}
})
它工作正常,但当列表非常大时,它有点慢。 我试图用另一个lapply来改变for循环但是当列表很大时需要更多的时间,因为for循环中的return()就像“break”一样。这不能在lapply()中完成,它会尝试列表中的每个元素。
我对所有可能有帮助的建议持开放态度。