18

我有一个辅助函数(比如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)返回taxon,modelz列,而foo(d2)只返回taxonand z

如果foo包含select(data,c(taxon,model,z))foo(d2)失败(因为d2不包含model)。如果我使用select(data,-pss)thenfoo(d1)类似地失败。

如果我从 tidyverse 撤退(只是 return ),我知道如何做到这一点data[vars],但我想知道是否有一种方便的方法可以做到这一点,或者(1)使用某种select()助手(tidyselect::select_helpers)或(2)使用 tidyeval(其中我没有找到时间让我的头脑转转!)

4

3 回答 3

23

另一种选择是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

输入?dplyr::selectR,你会发现:

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

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

any_of():与 all_of() 相同,但不为不存在的名称引发错误。

于 2018-07-26T01:04:27.523 回答
7

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

d1 %>%
    select(one_of(c("taxon", "model", "z")))
d2 %>%
    select(one_of(c("taxon", "model", "z")))
于 2018-07-26T00:18:32.000 回答
5

使用内置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
于 2018-07-26T00:44:39.737 回答