虽然标题看起来很简单,但我还没有在StackOverflow上找到答案。 我的问题是:我有一些元素的列表。列表的每个元素还包含一个填充了一些字符串的列表。列表内的列表包含空('')的值,而不是null。我想删除该列表中空的行。怎么办呢?我猜lapply可以做到这一点,但我不知道如何在那里使用它。
将不胜感激!非常感谢!
编辑: 所以我的输出看起来像这样
$'1'
1 text1
2 text2
3
4 text3
5 text4
$'2'
1 text1
2
3 text2
4
5 text3
我的目标是删除那些空的行,使其看起来像这样:
$'1'
1 text1
2 text2
3 text3
4 text4
$'2'
1 text1
2 text2
3 text3
答案 0 :(得分:7)
你说得对,你可以在这里使用lapply
。
test <- list(c("text1", "text2", "", "text3", "text4"),
c("text1", "", "text2", "", "text3"))
lapply(1:length(test), function(x) test[[x]][test[[x]] != ""])
[[1]]
[1] "text1" "text2" "text3" "text4"
[[2]]
[1] "text1" "text2" "text3"
答案 1 :(得分:0)
这是一个非常棘手的问题。首先,我合成了一些测试数据:
l <- list(list('a','b','','c','','d'),list('','e',''));
l;
## [[1]]
## [[1]][[1]]
## [1] "a"
##
## [[1]][[2]]
## [1] "b"
##
## [[1]][[3]]
## [1] ""
##
## [[1]][[4]]
## [1] "c"
##
## [[1]][[5]]
## [1] ""
##
## [[1]][[6]]
## [1] "d"
##
##
## [[2]]
## [[2]][[1]]
## [1] ""
##
## [[2]][[2]]
## [1] "e"
##
## [[2]][[3]]
## [1] ""
##
##
这是我的解决方案:
matches <- do.call(rbind,lapply(seq_along(l),function(li) cbind(li,which(do.call(c,l[[li]])==''))));
matches;
## li
## [1,] 1 3
## [2,] 1 5
## [3,] 2 1
## [4,] 2 3
invisible(apply(matches[rev(seq_len(nrow(matches))),],1,function(lri) l[[lri]] <<- NULL));
l;
## [[1]]
## [[1]][[1]]
## [1] "a"
##
## [[1]][[2]]
## [1] "b"
##
## [[1]][[3]]
## [1] "c"
##
## [[1]][[4]]
## [1] "d"
##
##
## [[2]]
## [[2]][[1]]
## [1] "e"
##
##
这使用递归列表索引。 Extract or Replace Parts of an Object:
中记录了这种类型的索引[[可以递归地应用于列表,因此如果单个索引i是长度为p的向量,alist [[i]]等同于alist [[i1]] ... [[ip]]提供除最终索引之外的所有索引都会列在列表中。
此解决方案还利用了将NULL
分配给列表组件删除该组件的事实。从同一文档页面:
请注意,在所有三种替换中,NULL值都会删除列表中的相应项。要将条目设置为NULL,您需要x [i]&lt; - list(NULL)。
首先删除索引较高的组件也很重要;否则,通过删除较低的索引,预先计算的较高索引将无效。因此,我在apply()
而不是matches[rev(seq_len(nrow(matches))),]
上运行matches
。
实际上还有另一种更简单的方法,包括重建列表,省略不需要的元素:
lapply(l,function(l2) l2[do.call(c,l2)!=''])
## [[1]]
## [[1]][[1]]
## [1] "a"
##
## [[1]][[2]]
## [1] "b"
##
## [[1]][[3]]
## [1] "c"
##
## [[1]][[4]]
## [1] "d"
##
##
## [[2]]
## [[2]][[1]]
## [1] "e"
##
##