基于多个具有相似命名结构的列进行过滤
Filter based on several columns with similar naming structure
我想 filter
我的 tibble
在几个名称相似的专栏上。具体来说,我想将 x
与 x_new
、y
与 y_new
等进行比较,但不指定显式名称,而是使用列名称中的结构。
我尝试使用 filter_at
,但这不起作用,因为我不知道如何正确计算最后一行中的公式。
my_df %>%
filter_at(vars(contains("_new")), any_vars(funs({
x <- .
x_name <- quo_name(quo(x))
x_new_name <- str_replace(x_name, "_new", "")
paste(x_name, "!=", x_new_name)
})
))
数据
my_df <- tibble(x = 1:5,
x_new = c(1:4, 1),
y = letters[1:5],
y_new = c(letters[1:3], "a", "e"))
# A tibble: 5 x 4
# x x_new y y_new
# <int> <dbl> <chr> <chr>
# 1 1 1. a a
# 2 2 2. b b
# 3 3 3. c c
# 4 4 4. d a
# 5 5 1. e e
预期输出
# A tibble: 2 x 4
# x x_new y y_new
# <int> <dbl> <chr> <chr>
# 1 4 4. d a
# 2 5 1. e e
我们可以用 map
做到这一点。通过删除列名 ('nm1') 的后缀部分,创建一个包含 unique
个名称的向量。遍历 'nm1'、select 列 matches
列名称,reduce
通过检查行是否不相等将其循环到单个逻辑向量,然后 reduce
将 list
个逻辑向量转换为单个逻辑向量,并 extract
基于该
的行
library(tidyverse)
nm1 <- unique(sub("_.*", "", names(my_df)))
map(nm1, ~ my_df %>%
select_at(vars(matches(.x))) %>%
reduce(`!=`)) %>%
reduce(`|`) %>%
magrittr::extract(my_df, ., )
# x x_new y y_new
# <int> <dbl> <chr> <chr>
#1 4 4 d a
#2 5 1 e e
另一种选择是创建一个表达式然后求值
library(rlang)
nm1 <- names(my_df) %>%
split(sub("_.*", "", .)) %>%
map(~ paste(.x, collapse=" != ") %>%
paste0("(", ., ")")) %>%
reduce(paste, sep = "|")
my_df %>%
filter(!! parse_expr(nm1))
# A tibble: 2 x 4
# x x_new y y_new
# <int> <dbl> <chr> <chr>
#1 4 4 d a
#2 5 1 e e
我想 filter
我的 tibble
在几个名称相似的专栏上。具体来说,我想将 x
与 x_new
、y
与 y_new
等进行比较,但不指定显式名称,而是使用列名称中的结构。
我尝试使用 filter_at
,但这不起作用,因为我不知道如何正确计算最后一行中的公式。
my_df %>%
filter_at(vars(contains("_new")), any_vars(funs({
x <- .
x_name <- quo_name(quo(x))
x_new_name <- str_replace(x_name, "_new", "")
paste(x_name, "!=", x_new_name)
})
))
数据
my_df <- tibble(x = 1:5,
x_new = c(1:4, 1),
y = letters[1:5],
y_new = c(letters[1:3], "a", "e"))
# A tibble: 5 x 4
# x x_new y y_new
# <int> <dbl> <chr> <chr>
# 1 1 1. a a
# 2 2 2. b b
# 3 3 3. c c
# 4 4 4. d a
# 5 5 1. e e
预期输出
# A tibble: 2 x 4
# x x_new y y_new
# <int> <dbl> <chr> <chr>
# 1 4 4. d a
# 2 5 1. e e
我们可以用 map
做到这一点。通过删除列名 ('nm1') 的后缀部分,创建一个包含 unique
个名称的向量。遍历 'nm1'、select 列 matches
列名称,reduce
通过检查行是否不相等将其循环到单个逻辑向量,然后 reduce
将 list
个逻辑向量转换为单个逻辑向量,并 extract
基于该
library(tidyverse)
nm1 <- unique(sub("_.*", "", names(my_df)))
map(nm1, ~ my_df %>%
select_at(vars(matches(.x))) %>%
reduce(`!=`)) %>%
reduce(`|`) %>%
magrittr::extract(my_df, ., )
# x x_new y y_new
# <int> <dbl> <chr> <chr>
#1 4 4 d a
#2 5 1 e e
另一种选择是创建一个表达式然后求值
library(rlang)
nm1 <- names(my_df) %>%
split(sub("_.*", "", .)) %>%
map(~ paste(.x, collapse=" != ") %>%
paste0("(", ., ")")) %>%
reduce(paste, sep = "|")
my_df %>%
filter(!! parse_expr(nm1))
# A tibble: 2 x 4
# x x_new y y_new
# <int> <dbl> <chr> <chr>
#1 4 4 d a
#2 5 1 e e