dplyr检测值超出多列范围

hwazgwia  于 2023-01-28  发布在  其他
关注(0)|答案(4)|浏览(101)

我们来看一下以下数据

data <- tibble(a = letters[1:4], b1 = 10:13, b2 = 10:13, 
               b3 = c(9, 4, 11, 10), b4 = c(50, 10:12))
min <- 9
max <- 15

data
# A tibble: 4 × 5
  a        b1    b2    b3    b4
  <chr> <int> <int> <dbl> <dbl>
1 a        10    10     9    50
2 b        11    11     4    10
3 c        12    12    11    11
4 d        13    13    10    12

我想创建一个新列is_unexpected来控制值是否超出minmax范围。
当然,下面是一个缓慢的(在编写代码的意义上)方法。由于我有超过4列(都以“b”开始),我希望优化我的代码。我尝试过使用across(),但没有成功。

data %>% 
  mutate(is_unexpected = 
           if_else(b1 < min | b2 < min | b3 < min | b4 < min | 
                     b1 > max | b2 > max | b3 > max | b4 > max,
                   1, 0)
  )
xu3bshqb

xu3bshqb1#

使用if_any

data %>% 
  mutate(is_unexpected = +(if_any(b1:b4, ~ .x > max | .x < min)))

# A tibble: 4 × 6
  a        b1    b2    b3    b4 is_unexpected
  <chr> <int> <int> <dbl> <dbl>         <int>
1 a        10    10     9    50             1
2 b        11    11     4    10             1
3 c        12    12    11    11             0
4 d        13    13    10    12             0

或者使用between

data %>% 
  mutate(is_unexpected = +(if_any(b1:b4, ~ !between(.x, min, max))))
bihw5rsg

bihw5rsg2#

使用across

data %>% 
  rowwise() %>% 
  mutate(is_unexpected = any(across(b1:b4) > !!max | across(b1:b4) < !!min) * 1)
# A tibble: 4 × 6
# Rowwise: 
  a        b1    b2    b3    b4 is_unexpected
  <chr> <int> <int> <dbl> <dbl>         <dbl>
1 a        10    10     9    50             1
2 b        11    11     4    10             1
3 c        12    12    11    11             0
4 d        13    13    10    12             0

此处使用!!是因为如果 Dataframe 具有 * min * 或 * max * 变量,则使用这些变量而不是全局变量。

e5nszbig

e5nszbig3#

或者,请检查

data %>% mutate(across(where(is.numeric), ~ifelse(.x>min|.x>max, 1, 0), .names = 'new{col}'),
 is_unexpected= ifelse(rowSums(across(starts_with('new')))>0,1,0)) %>% 
select(-starts_with('new'))

创建于2023年1月25日,使用reprex v2.0.2

hjzp0vay

hjzp0vay4#

使用base R

data$is_expected <- +(rowSums(data[-1] > max) > 0|rowSums(data[-1] < min)> 0)
  • 输出
> data
# A tibble: 4 × 6
  a        b1    b2    b3    b4 is_expected
  <chr> <int> <int> <dbl> <dbl>       <int>
1 a        10    10     9    50           1
2 b        11    11     4    10           1
3 c        12    12    11    11           0
4 d        13    13    10    12           0

相关问题