【问题标题】:How do I select columns that may or may not exist?如何选择可能存在或不存在的列?
【发布时间】:2017-10-02 20:51:51
【问题描述】:

我有一个数据框,可能有也可能没有某些特定的列。如果它们确实存在,我想使用dplyr 选择列,如果不存在,则忽略我试图选择它们。这是一个例子:

# Load libraries
library(dplyr)

# Create data frame
df <- data.frame(year = 2000:2010, foo = 0:10, bar = 10:20)

# Pull out some columns
df %>% select(year, contains("bar"))

# Result
#    year bar
# 1  2000  10
# 2  2001  11
# 3  2002  12
# 4  2003  13
# 5  2004  14
# 6  2005  15
# 7  2006  16
# 8  2007  17
# 9  2008  18
# 10 2009  19
# 11 2010  20

# Try again for non-existent column
df %>% select(year, contains("boo"))

# Result
#data frame with 0 columns and 11 rows

在后一种情况下,我只想返回包含 year 列的数据框,因为 boo 列不存在。我的问题是为什么在后一种情况下我会得到一个空数据框,有什么好的方法可以避免这种情况并达到预期的结果?

编辑:会话信息

R version 3.3.3 (2017-03-06)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] dplyr_0.5.0

loaded via a namespace (and not attached):
[1] lazyeval_0.2.0   magrittr_1.5     R6_2.2.0         assertthat_0.2.0 DBI_0.6-1        tools_3.3.3     
[7] tibble_1.3.0     Rcpp_0.12.10    

【问题讨论】:

  • 我的 dplyr 版本无法重现此错误。你能分享sessionInfo()的结果吗?另外,您能否尝试从 GitHub (devtools::install_github("tidyverse/dplyr")) 安装 dplyr 的开发版本,看看是否可以解决问题?
  • 我已将会话信息添加到原始问题中。
  • 它使用 dplyr '0.5.0.9001' 提供正确的输出。
  • 这是一个错误 reported here 并于 2017 年 2 月修复。dplyr 0.6.0 预计很快会在 CRAN 上发布。
  • 啊哈!感谢您的帮助。

标签: r select dplyr


【解决方案1】:

这里有一个使用dplyr::select_if() 的小改动,如果您尝试select 列名不存在,则不会引发Unknown columns: 警告,在本例中为“bad_column”:

df %>% 
  select_if(names(.) %in% c('year', 'bar', 'bad_column'))

【讨论】:

    【解决方案2】:

    您可以使用any_of()(来自tidyselect 包):

    df %>% select(any_of(c("year", "boo")))
    

    【讨论】:

    • 我更喜欢这种方法,因为select(any_of(c())) 尊重列名的列出顺序,并在输出中相应地组织它们。
    【解决方案3】:

    dplyr的开发版中

    df %>%
       select(year, contains("boo"))
    #     year
    #1  2000
    #2  2001
    #3  2002
    #4  2003
    #5  2004
    #6  2005
    #7  2006
    #8  2007
    #9  2008
    #10 2009
    #11 2010
    

    给出预期的输出

    否则一种选择是使用one_of

    df %>%
       select(one_of("year", "boo"))
    

    如果该列不可用,则返回警告消息

    其他选项是matches

    df %>%
      select(matches("year|boo"))
    

    【讨论】:

    • 我认为这不能回答问题,这是关于 dplyr 中的一个明显错误。 select(year, contains("boo")) 应该在输出中包含 year
    • @Patronus 我展示了一种获得预期输出的方法。他的问题是`我只想返回一个带有年份列的数据框,因为列 boo 不存在`。
    • 也适用于“-”。 %&gt;% select(-one_of("not_wanted_variable")) 将从您的 data.frame 中删除 not_wanted_variable
    • 请注意,“matches”会返回任何包含“year”或“boo”的列,因此如果您有“year1”、“year2”等列名,这些都会被返回。跨度>
    • @SylviaRodriguez 这是一篇旧帖子。你可以用matches("^(year\\d+$)|boo")修改那些
    猜你喜欢
    • 2021-07-15
    • 1970-01-01
    • 2020-11-06
    • 1970-01-01
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 2012-07-19
    • 2020-03-15
    相关资源
    最近更新 更多