用“智能”步骤生成“理智”序列

时间:2014-03-28 22:10:57

标签: r function sequence

我需要产生一个理智的#34;序列,以便从gcombobox()填充gWidgets2。窗口小部件处理数据框中的行数,该数据框将通过head()进行子集化。所以顺序可以从5开始(不一定来自1)并跨越"智能"步骤直到nrow(DF)

我想出了以下实现:

sane_steps <- function(x){
  if(x<50){
    res <- seq.int(5, x, 5)
  } else if(x<100){
    res <- c(seq.int(5, 49, 5), seq.int(50, x, 10))
  } else if(x<1000){
    res <- c(seq.int(5, 49, 5), seq.int(50, 99, 10), seq.int(100, x, 100))
  } else if(x<10000){
    res <- c(seq.int(5, 49, 5), seq.int(50, 99, 10), seq.int(100, 999, 100), 
             seq.int(1000, x, 1000))
  } else {
    res <- c(seq.int(5, 49, 5), seq.int(50, 99, 10), seq.int(100, 999, 100), 
             seq.int(1000, 9999, 1000), seq.int(10000, x, 10000))
  }
  if(!any(res %in% x)) res <- c(res, x)
  return(res)
}

那样:

> sane_steps(99)
 [1]  5 10 15 20 25 30 35 40 45 50 60 70 80 90 99
> sane_steps(523)
 [1]   5  10  15  20  25  30  35  40  45  50  60  70  80  90 100 200 300 400 500 523
> sane_steps(4548)
 [1]    5   10   15   20   25   30   35   40   45   50   60   70   80   90  100  200
[17]  300  400  500  600  700  800  900 1000 2000 3000 4000 4548
> sane_steps(27304)
 [1]     5    10    15    20    25    30    35    40    45    50    60    70    80
[14]    90   100   200   300   400   500   600   700   800   900  1000  2000  3000
[27]  4000  5000  6000  7000  8000  9000 10000 20000 27304

是否有更有效的方式来定义sane_steps()?是否有一个现有的R功能,有助于产生这样的&#34;理智&#34;序列?

2 个答案:

答案 0 :(得分:2)

您可以手动预先创建序列和子集。

sane_steps <- (function() {
  master_seq <- unlist(lapply(seq_len(.Machine$double.digits), function(x) {
    by <- 10^x
    seq(by, 10*by, by)
  }))
  master_seq <- c(seq(5, 50, 5), master_seq[-seq_len(5)])
  function(y) c(master_seq[master_seq < y], y)
})()

实施例

> sane_steps(99)
 [1]  5 10 15 20 25 30 35 40 45 50 60 70 80 90 99
> sane_steps(523)
 [1]   5  10  15  20  25  30  35  40  45  50  60  70  80  90 100 100 200 300 400 500 523
> sane_steps(4548)
 [1]    5   10   15   20   25   30   35   40   45   50   60   70   80   90  100  100  200  300  400  500  600  700  800  900 1000 1000 2000 3000 4000
[30] 4548
> sane_steps(27304)
 [1]     5    10    15    20    25    30    35    40    45    50    60    70    80    90   100   100   200   300   400   500   600   700   800   900
[25]  1000  1000  2000  3000  4000  5000  6000  7000  8000  9000 10000 10000 20000 27304

答案 1 :(得分:1)

根据接受的答案,我提出了一个稍微调整过的版本:

seq_sane <- (function(){
  master_seq <- unlist(lapply(seq_len(.Machine$double.digits), function(x){
    by <- 10^x
    seq.int(by, 10*by-1, by)
  }))
  master_seq <- c(seq.int(1, 4, 1), seq.int(5, 50, 5), master_seq[-seq_len(5)])
  function(y) c(master_seq[master_seq < y], y)
})()
#lapply(c(9,10,11,49,50,51,99,100,101,999,1000,1001,9999,10000,10001,385744), seq_sane)
#lapply(c(99,523,4548,27304), seq_sane)

这:

  • 选择更合适的名称
  • 修复了输出中by个元素加倍的错误(例如100,1000等)
  • 使用seq.int应该更快
  • 它还允许小于5的值(扩展原始问题的范围)