【问题标题】:Filter list objects based on attribute in R根据R中的属性过滤列表对象
【发布时间】:2017-10-18 07:21:18
【问题描述】:

我想构造一个对象列表并根据其中一个属性提取对象。例如

persons_list <- list(PersonA = list(color = 'red', group = 1),
                     PersonsB = list(color = 'blue', group = 1),
                     PersonsC = list(color = 'green', group = 2))

现在我想将所有颜色提取为一个向量,其中 group 等于 1,结果是:

c('red', 'blue')

我不确定列表是否适合这里,但我选择它是因为我还希望能够通过键入来使用列表的自动完成/浏览功能

persons_list$PersonA

【问题讨论】:

    标签: r list filter subset


    【解决方案1】:

    我们可以的

    unlist(lapply(persons_list, function(x) x$color[x$group==1]), use.names = FALSE)
    #[1] "red"  "blue"
    

    【讨论】:

      【解决方案2】:

      Akrun 总是更快。 :-)

      更一般地说。您可以构建一些通用功能来完成这项工作,而无需太多的认知努力。我还没有构建任何工具来从列表中选择内容。但我可以用

      remove_if <- function(lst,test_fn) {
          ## DD . char or list
          if (class(lst)=="character"){
              unlist(lapply(lst ,function(x){if(!(test_fn(x))) x }))
          } else {
      
             remove_if_null(lapply(lst ,function(x){if(!(test_fn(x))) x }))}
          }
      

      它会删除第 2 组,然后选择您需要的部分。

      unlist(lapply(remove_if(persons_list, function(x) x$group==2),"[[",1))

      ## PersonA PersonsB 
      ##   "red"   "blue" 
      

      【讨论】:

        【解决方案3】:

        不,该数据结构不适合您的用例。使用 data.frame:

        persons <- data.frame(person = c("A", "B", "C"),
                              color = c("red", "blue", "green"),
                              group = c(1, 1, 2),
                              stringsAsFactors = FALSE)
        persons[persons$group == 1, "color"]
        #[1] "red"  "blue"
        

        表格结构不仅更自然,查找也更高效。

        【讨论】:

          【解决方案4】:

          library(rlist) 有一堆很好的以列表为中心的函数,可以为列表操作带来一些整洁的动词。

          library(rlist)
          library(magrittr)
          
          list.filter(persons_list, group == 1) %>%
              list.select(color) %>%
              unlist(use.names = F)
          

          【讨论】:

            【解决方案5】:

            我知道这是旧的,但我错过了更一般的答案。

            我会使用:

            unlist(lapply(persons_list[which(sapply(persons_list, function(person) { person$group==1 }))], function(x) x$color), use.name = FALSE)
            

            或者为了便于阅读,我可能会将其分成两行:

            第一个过滤器

            persons_in_group_1 = persons_list[which(sapply(persons_list, function(person) { person$group==1 }))]
            

            然后映射所需的属性:

            unlist(lapply(persons_in_group_1, function(x) x$color ), use.names = FALSE)
            

            【讨论】:

              猜你喜欢
              • 2021-08-10
              • 2013-07-05
              • 1970-01-01
              • 2019-12-07
              • 2016-12-27
              • 2018-04-07
              • 2015-05-30
              • 2019-12-21
              • 2018-12-25
              相关资源
              最近更新 更多