匹配运算符行为异常

Match Operator behaving strangely

所以我有一个数据框:

BMI<-c(18,25.2,31.5,19.6,11.1,25.2)
AGE<-c(21,35,45,60,99,21)
df<-data_frame(BMI,AGE)

当我将匹配运算符与年龄一起使用时,它工作得很好(那些 30-50 岁显示为 true):

df<-df%>%mutate(MediumAge=if_else(AGE%in%30:50,TRUE,FALSE))

当我将匹配运算符与 BMI 一起使用时,它不会(BMI 在该范围内的人不会显示为 TRUE,唯一显示为 TRUE 的是恰好 18 个人):

df<-df%>%mutate(Medium=if_else(BMI%in%18:29,TRUE,FALSE))

显然 18 BMI 可能不是 "Medium" 但为了示例中的简单数据...

一定与小数位有关,但我在文档或解决方案中找不到任何内容

%in% 运算符是 match 的包装器。它不查看值的范围,而是尝试在向量中找到值的匹配项。它们不必是数字。例如:

library(tidyverse)

letters[1:6]
#> [1] "a" "b" "c" "d" "e" "f"
"e" %in% letters[1:6]
#> [1] TRUE

18:29 处,您正在创建一个整数向量,然后在该向量中查找 BMI 值的匹配项。这就是 BMI = 18 得到 TRUE 的原因,因为那个确切的数字在那个向量中,但是 25.2 在那个向量中是 而不是 ,所以它 returns FALSE.

打印出要测试的向量更容易看出:

30:50
#>  [1] 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
35 %in% 30:50
#> [1] TRUE

18:29
#>  [1] 18 19 20 21 22 23 24 25 26 27 28 29
25.2 %in% 18:29
#> [1] FALSE

所以既然你想知道一个值是否在两个数字之间的连续范围中,你可以使用不等式:

df %>%
  mutate(Medium = (BMI >= 18 & BMI <= 29))
#> # A tibble: 6 x 3
#>     BMI   AGE Medium
#>   <dbl> <dbl> <lgl> 
#> 1  18      21 TRUE  
#> 2  25.2    35 TRUE  
#> 3  31.5    45 FALSE 
#> 4  19.6    60 TRUE  
#> 5  11.1    99 FALSE 
#> 6  25.2    21 TRUE

dplyr::between,这是上述不等式的 shorthand,包括其端点。

df %>%
  mutate(Medium = between(BMI, 18, 29))
#> # A tibble: 6 x 3
#>     BMI   AGE Medium
#>   <dbl> <dbl> <lgl> 
#> 1  18      21 TRUE  
#> 2  25.2    35 TRUE  
#> 3  31.5    45 FALSE 
#> 4  19.6    60 TRUE  
#> 5  11.1    99 FALSE 
#> 6  25.2    21 TRUE

同样值得注意的是,如果您只是想取回一个逻辑值,您可以跳过 ifelse,因为这些检查方法中的任何一种都已经 return 了一个逻辑值。