【问题标题】:Make a list of objects that may or may not exist列出可能存在或不存在的对象
【发布时间】:2021-01-26 09:35:04
【问题描述】:

是否有从对象构建列表的选项,包括那些不一定存在的对象(因此应该简单地忽略)?

示例

my_df <- data.frame(some_values = letters[1:10])
my_vec <- 1:10
my_matrix <- matrix(1:9, nrow = 3, ncol = 3)

list(my_df, my_vec, my_matrix)
#> [[1]]
#>    some_values
#> 1            a
#> 2            b
#> 3            c
#> 4            d
#> 5            e
#> 6            f
#> 7            g
#> 8            h
#> 9            i
#> 10           j
#> 
#> [[2]]
#>  [1]  1  2  3  4  5  6  7  8  9 10
#> 
#> [[3]]
#>      [,1] [,2] [,3]
#> [1,]    1    4    7
#> [2,]    2    5    8
#> [3,]    3    6    9

list(my_df, my_vec, my_matrix, my_object_doesnt_exist)
#> Error in eval(expr, envir, enclos): object 'my_object_doesnt_exist' not found

reprex package (v0.3.0) 于 2021-01-26 创建

期望的输出

list(my_df, my_vec, my_matrix, my_object_doesnt_exist) 将返回与 list(my_df, my_vec, my_matrix) 相同的输出。

【问题讨论】:

    标签: r list


    【解决方案1】:

    您可以使用mgetFilter 喜欢:

    tt <- Filter(Negate(is.null), mget(c("my_df", "my_vec", "my_matrix"
     , "my_object_doesnt_exist"), ifnotfound=list(NULL)))
    
    identical(unname(tt), list(my_df, my_vec, my_matrix))
    #[1] TRUE
    

    【讨论】:

    • 谢谢!我希望它不会超出本文的范围——我想将您的代码包装在一个函数build_list() 中,该函数将接收对象并返回列表。但是,它只返回一个名称向量。 build_list &lt;- function(...) { args_as_expression &lt;- substitute(list(...)) args_as_char_vector &lt;- sapply(args_as_expression,deparse)[-1] Filter(Negate(is.null), mget(args_as_char_vector, envir = .GlobalEnv), ifnotfound = list(NULL))) }。你碰巧知道如何将你的解决方案包装在一个函数中吗?
    • 试试:build_list &lt;- function(...) {Filter(Negate(is.null), mget(sapply(substitute(list(...)), deparse)[-1], ifnotfound=list(NULL), inherits = TRUE))}
    【解决方案2】:

    类似的东西怎么样?

    my_df <- data.frame(some_values = letters[1:10])
    my_vec <- 1:10
    my_matrix <- matrix(1:9, nrow = 3, ncol = 3)
    
    list(my_df, my_vec, my_matrix)
    #> [[1]]
    #>    some_values
    #> 1            a
    #> 2            b
    #> 3            c
    #> 4            d
    #> 5            e
    #> 6            f
    #> 7            g
    #> 8            h
    #> 9            i
    #> 10           j
    #> 
    #> [[2]]
    #>  [1]  1  2  3  4  5  6  7  8  9 10
    #> 
    #> [[3]]
    #>      [,1] [,2] [,3]
    #> [1,]    1    4    7
    #> [2,]    2    5    8
    #> [3,]    3    6    9
    
    
    res <- lapply(c("my_df", "my_vec", "my_matrix", "my_object_doesnt_exist"),
                  function(x) if (exists(x)) get(x) else NA)
    
    res
    #> [[1]]
    #>    some_values
    #> 1            a
    #> 2            b
    #> 3            c
    #> 4            d
    #> 5            e
    #> 6            f
    #> 7            g
    #> 8            h
    #> 9            i
    #> 10           j
    #> 
    #> [[2]]
    #>  [1]  1  2  3  4  5  6  7  8  9 10
    #> 
    #> [[3]]
    #>      [,1] [,2] [,3]
    #> [1,]    1    4    7
    #> [2,]    2    5    8
    #> [3,]    3    6    9
    #> 
    #> [[4]]
    #> [1] NA
    
    # take only non NA values!
    res[!is.na(res)]
    #> [[1]]
    #>    some_values
    #> 1            a
    #> 2            b
    #> 3            c
    #> 4            d
    #> 5            e
    #> 6            f
    #> 7            g
    #> 8            h
    #> 9            i
    #> 10           j
    #> 
    #> [[2]]
    #>  [1]  1  2  3  4  5  6  7  8  9 10
    #> 
    #> [[3]]
    #>      [,1] [,2] [,3]
    #> [1,]    1    4    7
    #> [2,]    2    5    8
    #> [3,]    3    6    9
    

    reprex package (v0.3.0) 于 2021-01-26 创建

    【讨论】:

      【解决方案3】:

      exists():

      objects <- c("my_df", "my_vec", "my_matrix", "my_object_doesnt_exist")
      mylist <- list()
      for (ob in objects) if (exists(ob)) mylist[[ob]] <- get(ob)
      

      没有for循环:

      mget(objects[sapply(objects, exists)])
      

      【讨论】:

        【解决方案4】:

        在一次通话中使用@David nice 解决方案和tidyverse

        library(tidyverse)
        map(c("my_df", "my_vec", "my_matrix", "my_object_doesnt_exist"),
            function(x) if (exists(x)) get(x) else NA) %>% 
          keep(~ all(!is.na(.x))) 
        # [[1]]
        #    some_values
        # 1            a
        # 2            b
        # 3            c
        # 4            d
        # 5            e
        # 6            f
        # 7            g
        # 8            h
        # 9            i
        # 10           j
        
        # [[2]]
        #  [1]  1  2  3  4  5  6  7  8  9 10
        
        # [[3]]
        #      [,1] [,2] [,3]
        # [1,]    1    4    7
        # [2,]    2    5    8
        # [3,]    3    6    9
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-10-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-15
          • 2011-10-03
          • 2012-03-14
          • 2011-09-06
          相关资源
          最近更新 更多