【问题标题】:Replace values outside of max/min values with max/min values用最大值/最小值替换最大值/最小值之外的值
【发布时间】:2019-08-12 18:54:15
【问题描述】:

有没有办法用用户一步确定的最大/最小阈值替换data.frame 列中高于或低于设置阈值的值?

data.table::between() 函数返回TRUEFALSE,但没有指示它是高于还是低于...

MWE 见下文。我可以分两步得到结果,但想知道是否已经有一个内置函数可以用最大/最小值替换高于/低于最大值/最小值的值。

谢谢。

library(data.table)
library(magrittr)

a <- data.table(colA = LETTERS[seq(1,10)],
                colB = 1:10)

the_max <- 7
the_min <- 3

# creates TRUE/FALSE column...
a[, colC := between(colB, the_min, the_max)]
a
#>     colA colB  colC
#>  1:    A    1 FALSE
#>  2:    B    2 FALSE
#>  3:    C    3  TRUE
#>  4:    D    4  TRUE
#>  5:    E    5  TRUE
#>  6:    F    6  TRUE
#>  7:    G    7  TRUE
#>  8:    H    8 FALSE
#>  9:    I    9 FALSE
#> 10:    J   10 FALSE

# gets the result...
a[, colD := colB] %>% 
  .[colD < the_min, colD := the_min] %>% 
  .[colD > the_max, colD := the_max]
a
#>     colA colB  colC colD
#>  1:    A    1 FALSE    3
#>  2:    B    2 FALSE    3
#>  3:    C    3  TRUE    3
#>  4:    D    4  TRUE    4
#>  5:    E    5  TRUE    5
#>  6:    F    6  TRUE    6
#>  7:    G    7  TRUE    7
#>  8:    H    8 FALSE    7
#>  9:    I    9 FALSE    7
#> 10:    J   10 FALSE    7

reprex package (v0.2.1) 于 2019 年 8 月 12 日创建

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    可以通过pmin/pmax完成

    a[, colD := pmin(pmax(the_min, colB), the_max)]
    a
    #    colA colB colD
    # 1:    A    1    3
    # 2:    B    2    3
    # 3:    C    3    3
    # 4:    D    4    4
    # 5:    E    5    5
    # 6:    F    6    6
    # 7:    G    7    7
    # 8:    H    8    7
    # 9:    I    9    7
    #10:    J   10    7
    

    【讨论】:

      【解决方案2】:

      参考这个帖子:Replace all values lower than threshold in R

      这应该更有效,但是它使用与 akrun 的答案相同的逻辑。

      pmaxmin <- 
        function(x, mmax, mmin) {
           `[<-`(x, x < mmin, mmin) -> y
           `[<-`(y, y > mmax, mmax) -> z
           z
       }
      
      a[, colD := pmaxmin(colB, the_max, the_min)][]
      
      #     colA colB colD
      #  1:    A    1    3
      #  2:    B    2    3
      #  3:    C    3    3
      #  4:    D    4    4
      #  5:    E    5    5
      #  6:    F    6    6
      #  7:    G    7    7
      #  8:    H    8    7
      #  9:    I    9    7
      # 10:    J   10    7
      

      附言你不需要magrittrdata.table 中执行多个步骤:

      a[, colD := colB][
        colD < the_min, colD := the_min][
          colD > the_max, colD := the_max]
      

      这与您的管道解决方案相同。

      【讨论】:

      • 谢谢。我使用%&gt;% 来保持线条垂直对齐。使用[ ] 将代码缓慢地向右移动(并链接多行将其移动得更远......)。如果您对此有解决方案,请分享! (尽管从我搜索的内容来看,使用%&gt;%[ ] 并没有真正的速度差异。
      • @Prevost 您可以选择对齐方式。我不确定你的意思。
      • 在您的代码 sn-p 链接 data.table 中,您正在创建的变量会向右移动每个引入的链。第三行 colD 比第二行 colD 更靠右。
      • @Prevost 这就是我想要的。我可以简单地删除多余的空间。在 R 中,缩进并不重要。
      • 缩进默认是在‘[]’中插入的,我不想拥有它也不想手动删除它所以我使用‘%>%’。
      猜你喜欢
      • 1970-01-01
      • 2023-04-02
      • 2011-12-22
      • 2014-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多