2014-03-28 23 views
1

我需要生成一个“理智”序列,以便从gWidgets2填充gcombobox()。小部件处理来自数据框的行数,该数据框将通过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功能,以促进这种“理智”的序列?

+0

这真的没有有什么范围)与gwidgets – Dason

+0

我绝对同意,但我认为这将是有益的给一些上下文。我应该删除'gwidgets'标签吗? – landroni

+0

当然,给上下文很好,但我不确定gwidgets标签是否必要。 – Dason

回答

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 
+0

非常好的实现。谢谢!我对'(function(){..})()'语法很好奇。这是正统吗? (另外,代码中存在一些小问题,并将修改后的版本发布在单独的答案中。) – landroni

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(扩大原题的