【问题标题】:dplyr::select() with some variables that may not exist in the data frame?dplyr::select() 带有一些可能不存在于数据框中的变量?
【发布时间】:2019-01-02 21:16:47
【问题描述】:

我有一个辅助函数(比如foo()),它将在可能包含或不包含指定变量的各种数据帧上运行。假设我有

library(dplyr)
d1 <- data_frame(taxon=1,model=2,z=3)
d2 <- data_frame(taxon=2,pss=4,z=3)

我要选择的变量是

vars <- intersect(names(data),c("taxon","model","z"))

也就是说,我希望foo(d1) 返回taxonmodelz 列,而foo(d2) 只返回taxonz

如果foo 包含select(data,c(taxon,model,z)),则foo(d2) 失败(因为d2 不包含model)。如果我使用select(data,-pss),那么foo(d1) 同样会失败。

如果我从 tidyverse 撤退,我知道该怎么做(只需返回 data[vars]),但我想知道是否有一种方便的方法(1)使用某种 select() 助手( tidyselect::select_helpers) 或 (2) 与 tidyeval (我仍然还没有找到时间去思考!)

【问题讨论】:

    标签: r select dplyr nse tidyselect


    【解决方案1】:

    另一个选项是select_if:

    d2 %>% select_if(names(.) %in% c('taxon', 'model', 'z'))
    
    # # A tibble: 1 x 2
    #   taxon     z
    #   <dbl> <dbl>
    # 1     2     3
    

    select_if 已被取代。请改用any_of

    d2 %>% select(any_of(c('taxon', 'model', 'z')))
    # # A tibble: 1 x 2
    #   taxon     z
    #   <dbl> <dbl>
    # 1     2     3
    

    在 R 中输入?dplyr::select,你会发现:

    这些助手从字符向量中选择变量:

    all_of():匹配字符向量中的变量名。所有名字都必须 存在,否则会引发越界错误。

    any_of():与 all_of() 相同,只是不会对名称抛出错误 不存在的。

    【讨论】:

    • 所有答案都很好,但这个答案简洁易读,不会引发任何警告。 (@G.Grothendieck 最接近我给出的方法)。
    • 或:d2 %&gt;% select(which(names(.) %in% c('taxon', 'model', 'z')))
    • 有替代品总是好的,但select_if(...) 似乎比select(which(...)) 更好
    • select_if (names(.)... 对于较大的 data.frames 来说非常非常慢。
    【解决方案2】:

    您可以使用one_of(),当列不存在时会发出警告,否则会选择正确的列:

    d1 %>%
        select(one_of(c("taxon", "model", "z")))
    d2 %>%
        select(one_of(c("taxon", "model", "z")))
    

    【讨论】:

    • one_of() 已停用,取而代之的是 any_of()(适用于此处)或 all_of()(如果变量不存在,则会出错)。
    【解决方案3】:

    使用内置的 anscombe 数据框作为示例,注意 z 不是 anscombe 中的列:

    anscombe %>% select(intersect(names(.), c("x1", "y1", "z")))
    

    给予:

       x1    y1
    1  10  8.04
    2   8  6.95
    3  13  7.58
    4   9  8.81
    5  11  8.33
    6  14  9.96
    7   6  7.24
    8   4  4.26
    9  12 10.84
    10  7  4.82
    11  5  5.68
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-15
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      • 2021-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多