9

我正在做一个项目,我需要在 R 中输入许多“T 分数”表。这些表用于将原始测试分数转换为标准化值。它们通常遵循一种特定的模式,但不是一种简单的模式。例如,一种模式是:

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() 函数可以创建一个简单的序列,例如:

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()。

4

3 回答 3

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
于 2012-07-17T22:01:23.640 回答
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
于 2012-07-17T22:07:50.200 回答
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
于 2012-07-17T23:00:52.023 回答