2012-07-17 29 views
9

我正在开发一个项目,我需要在R中输入一些“T分数”表格。这些表格用于将原始测试分数转换为标准化值。它们通常遵循特定的模式,但不是那种简单的模式。举例来说,一个模式是:使用标准模式在R中生成数字序列

34,36,39,42,44,47,50,52,55,58,60,63,66,68, 
71,74,76,79,82,84,87,90,92,95,98,100,103,106 

我宁愿使用一个简单的函数来填补这些,而不是手动输入。我知道,SEQ()函数可以创建一个简单seqeuence,如:

R> seq(1,10,2) 
[1] 1 3 5 7 9 

有什么方法来创建基于特定的图案更复杂的序列?例如,上述数据可以做到:

c(34,seq(36:106,c(3,3,2)) # The pattern goes 36,39,42,44,47,50,52 (+3,+3,+2) 

...但是,这会导致错误。我认为应该有这样一个功能,但我所有的Google-fu都把我带回了原来的seq()。

+0

感谢所有伟大的答案。 cumsum()看起来将是最好的选择! – TARehman 2012-07-18 14:33:49

回答

10

这可以使用cumsum(累积和)功能和rep来完成:

> 31 + cumsum(rep(c(3, 2, 3), 9)) 
[1] 34 36 39 42 44 47 50 52 55 58 60 63 66 68 71 74 76 79 82 
[20] 84 87 90 92 95 98 100 103 

为了确保确定的顺序停在正确的地方:

> (31 + cumsum(rep(c(3, 2, 3), 10)))[1:28] 
[1] 34 36 39 42 44 47 50 52 55 58 60 63 66 68 71 74 76 79 82 
[20] 84 87 90 92 95 98 100 103 106 
9

这里是一个自定义函数这应该在大多数情况下工作。它使用序列的累积和(cumsum())和整数除法来计算所需序列的长度。

cseq <- function(from, to, by){ 
    times <- (to-from) %/% sum(by) 
    x <- cumsum(c(from, rep(by, times+1))) 
    x[x<=to] 
} 

试试:

> cseq(36, 106, c(3,3,2)) 
[1] 36 39 42 44 47 50 52 55 58 60 63 66 68 71 74 76 79 82 84 87 90 92 95 98 
[25] 100 103 106 

> cseq(36, 109, c(3,3,2)) 
[1] 36 39 42 44 47 50 52 55 58 60 63 66 68 71 74 76 79 82 84 87 90 92 95 98 
[25] 100 103 106 108 
3

这里是一个非迭代的解决方案,如果你需要的序列的特定元素

f <- function(x){ 
d <- (x) %/% 3 
r <- x %% 3 
31 + d*8 + c(0,3,5)[r+1] 
} 

> f(1:10) 
[1] 34 36 39 42 44 47 50 52 55 58