这是一个使用tidyverse 的选项,我们利用purrr 中的map 和reduce 函数来获得逻辑vector 到extract(来自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
这也可以使用dplyr(即将发布0.6.0)的开发版本转换为函数,其中引入了quosures和unquote进行评估。 enquo 与base R 中的substitute 几乎相似,后者接受用户输入并将其转换为quosure,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
df %>%
filter(do.call(pmax, .) > 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