首页 文章

在R:子集或dplyr :: filter中,带有来自vector的变量

提问于
浏览
4
df <- 
  data.frame(a=LETTERS[1:4],
             b=rnorm(4)
             )

vals <- c("B","D")

我可以使用 val 中的值过滤/子集 df

dplyr::filter(df, a %in% vals)
subset(df, a %in% vals)

两者都给出:

a         b
2 B 0.4481627
4 D 0.2916513

如果我在向量中有变量名,例如:

> names(df)[1]
[1] "a"

然后它不起作用 - 我猜因为它的引用

dplyr::filter(df, names(df)[1] %in% vals)
[1] a b
<0 rows> (or 0-length row.names)

你怎么做到这一点 ?

UPDATE ( what if its dplyr::tbl_df(df) )

下面的答案适用于data.frames,但不适用于dplyr :: tbl_df包装数据:

df<-dplyr::tbl_df(df)
dplyr::filter(df, df[,names(df)[1]] %in% vals)

不起作用(我认为 tbl_df 是df顶部的简单包装?)

这确实有效:

dplyr::filter(df, as.data.frame(df)[,names(df)[1]] %in% vals)

FINAL UPDATE: It works with tbl_df() using lazyeval::interp

请参阅下面的AndreyAkinshin的解决方案 .

2 回答

  • 1

    您可以使用 df[,"a"]df[,1]

    df <- data.frame(a = LETTERS[1:4], b = rnorm(4))
    vals <- c("B","D")
    
    dplyr::filter(df, df[,1] %in% vals)
    #  a         b
    # 2 B 0.4481627
    # 4 D 0.2916513
    
    subset(df, df[,1] %in% vals)
    #  a         b
    # 2 B 0.4481627
    # 4 D 0.2916513
    
    dplyr::filter(df, df[,"a"] %in% vals)
    #  a         b
    # 2 B 0.4481627
    # 4 D 0.2916513
    
    subset(df, df[,"a"] %in% vals)
    #  a         b
    # 2 B 0.4481627
    # 4 D 0.2916513
    

    Working with dplyr::tbl_df(df)

    lazyeval::interp 的一些魔力帮助我们!

    df <- dplyr::tbl_df(df)
    expr <- lazyeval::interp(quote(x %in% y), x = as.name(names(df)[1]), y = vals)
    
    df %>% filter_(expr)
    # Source: local data frame [2 x 2]
    #
    #   a        b
    # 1 B 0.4481627
    # 2 D 0.2916513
    
  • 6

    在tidyverse中解决此问题的简单方法:

    library(tidyverse)
    df <- data.frame(a = LETTERS[1:4], b = rnorm(4))
    vals <- c("B","D")
    df %>% filter(!!sym(names(.)[1]) %in% vals)
    

相关问题