使用dplyr根据一列过滤所有列

时间:2017-04-15 09:30:34

标签: r dplyr

我想使用dplyr过滤至少一列(不包括P大于P)的行。试图找出一个过滤所有列的解决方案。

实施例

library(dplyr)

df <-  tibble(P = c(2,4,5,6,1.4), B = 
                c(2.1,3,5.5,1.2, 2), 
                C = c(2.2, 3.8, 5.7, 5,
                  1.5))

期望的输出

df <- filter(df, B > P | C > P)
df

使用apply的一种解决方案,如果可能的话我想避免使用:

filter(df, apply(df, 1, function(x) sum(x > x[1]) > 1))

2 个答案:

答案 0 :(得分:2)

没有def add_item(): backpack = [] i = 0 while 1: i += 1 item = raw_input(" > ") if item == '': break backpack.append(item) print "\nAh, the %s, let us hope this serves you well." % item print "This is the inventory you have acquired so far..." print backpack def dizzygas_hallway(): print "If so which item do you choose? (cloak or pendant)" add_item() def dark_laboratory(): print "Which item do you take? (book, potion or sword)\n" add_item() print "You exit the only door in sight..." dizzygas_hallway() ...

dplyr

df2 <- df[df$P!=apply(df,1,max),] ...

dplyr

答案 1 :(得分:2)

以下是使用map的选项,我们使用reduce中的purrrvector函数来获取逻辑extract到{{1} (来自magrittr)原始数据集的行

library(tidyverse)
library(magrittr)
df %>% 
    select(-one_of("P")) %>% 
    map(~ .> df$P) %>% 
    reduce(`|`) %>%
    extract(df, .,)
# A tibble: 3 × 3
#      P     B     C
#  <dbl> <dbl> <dbl>
#1   2.0   2.1   2.2
#2   5.0   5.5   5.7
#3   1.4   2.0   1.5

这也可以使用devel版本dplyr(即将发布0.6.0)转换为函数,该版本引入quosuresunquote进行评估。 enquosubstitute的{​​{1}}几乎相似,它接受用户输入并将其转换为base Rquosure接受字符串参数,因此可以转换与one_of

字符串
quo_name

我们也可以解析表达式

funFilter <- function(dat, colToCompare){
   colToCompare <- quo_name(enquo(colToCompare))

   dat %>%
       select(-one_of(colToCompare)) %>%
       map(~ .> dat[[colToCompare]]) %>%
       reduce(`|`) %>%
       extract(dat, ., )
}

funFilter(df, P)#compare all other columns with P
# A tibble: 3 × 3
#      P     B     C
#  <dbl> <dbl> <dbl>
#1   2.0   2.1   2.2
#2   5.0   5.5   5.7
#3   1.4   2.0   1.5

funFilter(df, B) #compare all other columns with B
# A tibble: 4 × 3
#      P     B     C
#  <dbl> <dbl> <dbl>
#1     2   2.1   2.2
#2     4   3.0   3.8
#3     5   5.5   5.7
#4     6   1.2   5.0

这也可以成为一个函数

v1 <- setdiff(names(df), "P")
filter(df, !!rlang::parse_quosure(paste(v1, "P", sep=" > ", collapse=" | ")))
# A tibble: 3 × 3
#     P     B     C
#    <dbl> <dbl> <dbl>
#1   2.0   2.1   2.2
#2   5.0   5.5   5.7
#3   1.4   2.0   1.5

或者另一种方法可能是funFilter2 <- function(dat, colToCompare){ colToCompare <- quo_name(enquo(colToCompare)) v1 <- setdiff(names(dat), colToCompare) expr <- rlang::parse_quosure(paste(v1, colToCompare, sep= " > ", collapse= " | ")) dat %>% filter(!!expr) } funFilter2(df, P) # A tibble: 3 × 3 # P B C # <dbl> <dbl> <dbl> #1 2.0 2.1 2.2 #2 5.0 5.5 5.7 #3 1.4 2.0 1.5 funFilter2(df, B) # A tibble: 4 × 3 # P B C # <dbl> <dbl> <dbl> #1 2 2.1 2.2 #2 4 3.0 3.8 #3 5 5.5 5.7 #4 6 1.2 5.0

pmax