【问题标题】:Match Operator behaving strangely匹配操作员行为异常
【发布时间】:2018-08-21 14:08:19
【问题描述】:

所以我有一个数据框:

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)

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

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

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

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

显然 18 的 BMI 可能不是“中等”,但为了示例中的简单数据......

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

【问题讨论】:

  • 也许使用between? (dplyr 包)
  • BMI 是数字浮点广告 18:29 给出整数值,它正在检查这些值是否完全匹配,但事实并非如此

标签: r dplyr operators match


【解决方案1】:

%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 不在该向量中,因此它返回 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,这是上述不等式的简写,包括其端点。

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,因为这些检查方法中的任何一种都将返回一个逻辑值。

【讨论】:

    猜你喜欢
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多