【问题标题】:Analog of subset for lists列表子集的模拟
【发布时间】:2012-08-22 18:12:43
【问题描述】:

我想根据其中一个子列表元素的内容对子列表列表进行子集化,其方式类似于 subset 处理数据框的方式:

sublist1 <- list(data=rnorm(10), name="name1", keepMe=2)
sublist2 <- list(data=rnorm(10), name="name2", keepMe=2)
sublist3 <- list(data=rnorm(10), name="name3", keepMe=3)
myList <- list(s1=sublist1, s2=sublist2, s3=sublist3)

我想做类似keepers &lt;- subset[myList, keepMe==2] 的操作,它会返回一个长度为 2 的列表。

以下是几乎我想要的:

require(plyr)
selector <- function(x) {
  if (x$keepMe==2) {return(x)} 
  else {return(NULL)}
}
keepers <- llply(myList, selector)

除了在这种情况下不需要的列表元素不会被丢弃,它们只是被NULL替换。

请注意,在所有情况下,子列表都将具有相同的组件,只有组件的值会发生变化。

【问题讨论】:

    标签: r


    【解决方案1】:

    这将在keepMe 位置为您提供两个带有 TRUE 的列表:

    myList[ unlist( sapply(myList, "[", "keepMe") ) ]
    

    @ttmaccer 解决方案省略了i=

    myList[ sapply(myList, "[[", "keepMe")  ]
    

    (成功是因为sapply 会尝试传递一个向量或矩阵,但“[”返回一个列表,而“[[”返回一个原子逻辑。)

    【讨论】:

    • 比我的解决方案好多了。 +1。我还没有完全弄清楚如何/何时将[[[ 等与apply 函数一起使用。有什么建议吗?
    • 我编辑了问题以更准确地反映我的实际问题:keepMe 元素将包含一个数字,我想选择某些数字/范围。我不太清楚如何将@DWin 的解决方案(这对我提出的问题很好)应用于我实际面临的问题。抱歉,DWin,关于这个变化。
    • 还要添加更短的版本。
    【解决方案2】:

    这个有效但是不知道有没有更直接的方法:

    keepers = myList[-(which(sapply(1:length(myList), 
                                    function(x) myList[[x]]$keepMe == FALSE)))]
    

    这是结果列表的str()

    str(keepers)
    # List of 2
    # $ s1:List of 3
    #  ..$ data  : num [1:10] -0.82 0.487 0.738 0.576 -0.305 ...
    #  ..$ name  : chr "name1"
    #  ..$ keepMe: logi TRUE
    # $ s2:List of 3
    #  ..$ data  : num [1:10] -0.0449 -0.0162 0.9438 0.8212 0.5939 ...
    #  ..$ name  : chr "name2"
    #  ..$ keepMe: logi TRUE
    

    【讨论】:

    • 似乎应该有更直接的方法,不是吗?涉及 sapply(myList, "[[", ...) 的东西 - 但我无法做到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多