R-根据跨多个列的值范围过滤行

R- filter rows depending on value range across several columns

我有 5 列数字数据,我想筛选出与 5 列中至少 3 列的数据范围匹配的行。

例如,我有以下数据框,我定义的值范围为 5-10。 我的第一行有 3 列,值在 5 到 10 之间,所以我想保留该行。 第二行只有5到10之间的2个值,所以我想删除它。

column1 column2 column3 column4 column5
7 4 10 9 2
4 8 2 6 2

首先测试列中的值是否大于或等于 5 且小于或等于 10,然后查找具有 3 或更多符合条件的行。

dat[ rowSums( dat >= 5 & dat <= 10 ) >= 3, ]
  column1 column2 column3 column4 column5
1       7       4      10       9       2

数据

dat <- structure(list(column1 = c(7L, 4L), column2 = c(4L, 8L), column3 = c(10L, 
2L), column4 = c(9L, 6L), column5 = c(2, 2)), class = "data.frame", row.names = c(NA, 
-2L))

我想分享第二种方法:

# Setting up data
my_df <- tibble::tibble(A = c(7,4), B = c(4,8), C = c(10, 2), D = c(9,6), E = c(2,2), X = c("some", "character"))
my_min <- 5
my_max <- 10

然后做一些 tidyverse-magic:

# This is verbose, but shows clearly all the steps involved:
my_df_filtered <- my_df %>% 
  dplyr::mutate(n_cols_in_range = dplyr::across(where(is.numeric), ~ .x >= my_min & .x <= my_max)
                ) %>%
  dplyr::rowwise() %>%
  dplyr::mutate(n_cols_in_range = sum(n_cols_in_range, na.rm = TRUE)
                ) %>%
  dplyr::filter(n_cols_in_range >= 3
                ) %>%
  dplyr::select(-n_cols_in_range)

以上等同于:

my_df_filtered <- my_df %>% 
  dplyr::rowwise() %>%
  dplyr::filter(sum(dplyr::across(where(is.numeric), ~ .x >= my_min & .x <= my_max), na.rm = TRUE) >= 3)

但我必须声明,上面的答案显然更优雅,因为它只需要 1 行代码!