提取向量中每个第n个元素

156

我想创建一个向量,其中每个元素都是另一个向量的i+6元素。

例如,在长度为120的向量中,我想创建另一个长度为20的向量,其中每个元素是初始向量的值i,i+6,i+12,i+18...,即我想提取原始向量的每个第6个元素。

5个回答

194
a <- 1:120
b <- a[seq(1, length(a), 6)]

11
对于长向量,最好使用seq.int(1L, length(a), 6L)。 - Wojciech Sobala
1
@WojciechSobala 你能否评论一下为什么这样做更好? - dpel
1
@DavidPell seq.int 在微基准测试中更快,但我怀疑在实际程序中的任何性能提升都会被其他部分的运行时间所掩盖。 - Sean1708
我不喜欢将Python和R进行比较,但PyRon会有多棒呢?a = 1:120; b = [::6]。Python无法做到前者,R也无法做到后者。 - bers

53

除了已经提到的使用seq解决方案外,获取连续片段的另一种技巧是使用一个短逻辑向量并利用向量循环:

foo[ c( rep(FALSE, 5), TRUE ) ]

4
这种方法的优点是它可以被用于临时操作;为了使用 seq,你必须能够在向量上调用 lengthletters[letters < 'm'][c(TRUE, FALSE, FALSE)] - Matt Chambers

29

我认为您在问两件不一定相同的事情。

我想提取原始序列中每个第6个元素。

您可以通过对序列进行索引来实现此操作:

foo <- 1:120
foo[1:20*6]
我想创建一个向量,其中每个元素都是另一个向量的第i+6个元素。
一个简单的方法是通过添加FALSE值,直到 i+6 为止,从而构建逻辑因子。
foo <- 1:120
i <- 1
foo[1:(i+6)==(i+6)]
[1]   7  14  21  28  35  42  49  56  63  70  77  84  91  98 105 112 119

i <- 10
foo[1:(i+6)==(i+6)]
[1]  16  32  48  64  80  96 112

太棒了!我也使用过相反的方式,即 foo[1:(i+6)!=(i+6)] ,即输出除第六个值以外的所有值。 - Fredrik Erlandsson
一个更通用的方法来对向量x进行每n个元素子集操作是 x[1:(length(x)/n)*n] - tjebo

2
从任何起始位置选择向量中的每个第n个元素。最初的回答。
nth_element <- function(vector, starting_position, n) { 
  vector[seq(starting_position, length(vector), n)] 
  }

# E.g.
vec <- 1:12

nth_element(vec, 1, 3)
# [1]  1  4  7 10

nth_element(vec, 2, 3)
# [1]  2  5  8 11

2
为了选择带有偏移/位移f=0,...,n-1的每个第n个元素,请使用以下方法:
vec[mod(1:length(vec), n)==f]

当然,你可以将此封装在一个漂亮的函数中:
nth_element <- function(vec, interval, offset=0){
    vec[mod(1:length(vec), interval)==mod(offset, interval)]
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接