根据数字的不同范围将数值映射到R中的分类值

问题描述:

希望我的标题有意义。我有一个有一列数值的数据框,我想用这个列来创建一个新列,根据这些列的值,数值被“映射”到不同的桶中。下面是一些测试数据,以及我目前用来解决这个问题的粗糙的边缘嵌套ifelse()方法。我希望在不涉及嵌套ifelse()语句更好的方式来编写这一点,因为这种方法不适用于许多水桶很好地扩展:根据数字的不同范围将数值映射到R中的分类值

mydf = data.frame(strings = letters[1:10], 
       numerics = c(0.2, 0.4, 1.3, 5.2, 3.3, 2.1, 7.3, 1.1, 4.3, 8.3), 
       stringsAsFactors = FALSE) 

这里是我的测试数据框,这里是我的嵌套ifelse()的方法来解决我的问题:

mydf$buckets = ifelse(mydf$numerics <= 2, 0, 
        ifelse(mydf$numerics <= 4, 1, 
         ifelse(mydf$numerics <= 5, 2, 
          ifelse(mydf$numerics <= 7, 3, 4)))) 

什么上面的代码确实是在数字列映射值如下:

  • 所有值< 2转至0
  • 所有值< 4转至1
  • 所有值< 5转到2
  • 所有值< 7转至3
  • 所有值> = 7去4

这种方法没有按”吨的规模很好,超过一小部分桶。任何与此有关的帮助表示赞赏!谢谢,

+3

'cut(mydf $ numerics,breaks = c(0,2,4,5,7,10),labels = c(0,1,2,3,4))' –

+1

'我认为你会对'dplyr'包中的'case_when'。它可以很好地扩展并且代码很清晰。 – tictocchoc

+1

从基地R'切'是专门为这种情况下设计的。对于非单调映射,可以创建一个查找表并合并。 – MichaelChirico

我真的很喜欢作为已经@tictocchoc在评论中提到这种情况下使用case_when

suppressPackageStartupMessages(library(tidyverse)) 

mydf = data.frame(strings = letters[1:10], 
        numerics = c(0.2, 0.4, 1.3, 5.2, 3.3, 2.1, 7.3, 1.1, 4.3, 8.3), 
        stringsAsFactors = FALSE) 

mydf %>% 
    mutate(buckets = case_when(
    numerics < 2 ~0, 
    numerics < 4 ~1, 
    numerics < 5 ~2,  
    numerics < 7 ~3, 
    numerics >= 7 ~4 
)) 
#> strings numerics buckets 
#> 1  a  0.2  0 
#> 2  b  0.4  0 
#> 3  c  1.3  0 
#> 4  d  5.2  3 
#> 5  e  3.3  1 
#> 6  f  2.1  1 
#> 7  g  7.3  4 
#> 8  h  1.1  0 
#> 9  i  4.3  2 
#> 10  j  8.3  4 
+0

是的,我喜欢这个解决方案 - 我认为基础R解决方案是但更简单,但这也是一个不错的解决方案。 – Canovice

尝试使用findInterval功能基础R:

findInterval(mydf$numerics,c(2,4,5,7)) 
    [1] 0 0 0 3 1 1 4 0 2 4 
+0

这是伟大的,我的问题比cut()更准确的解决方案,虽然cut()看起来有更多的用例 – Canovice