2014-09-25 94 views
2

我试图用NAs替换总和为零的矢量中的所有元素组。 每个组的大小为3。例如:r - 替换矢量中的元素组

a = c(0,0,0,0,2,3,1,0,2,0,0,0,0,1,2,0,0,0) 

应该是最后:

c(NA,NA,NA,0,2,3,1,0,2,NA,NA,NA,0,1,2,NA,NA,NA) 

到现在为止,我已经成功地通过找到具有相等的总和组零:

b = which(tapply(a,rep(1:(length(a)/3),each=3),sum) == 0) 

其产生c(1,4,6)

我然后计算通过:b <- b*3-2开始向量中组的索引。 也许有一种更优雅的方式,但这是我迄今缝合在一起的东西。 现在我被困在“扩展”开始索引的向量中,以生成要被替换的元素序列。例如,如果向量b现在包含c(1,10,16),则需要一个序列c(1,2,3,10,11,12,16,17,18),这些元素是要由NAs替换的元素的索引。 如果您对没有for循环的解决方案有任何想法,或者对于整个问题甚至是更简单/优雅的解决方案,我都会很感激。谢谢。

马吕斯

回答

2

您可以使用这样的事情:

a[as.logical(ave(a, 0:(length(a)-1) %/% 3, 
      FUN = function(x) sum(x) == 0))] <- NA 
a 
# [1] NA NA NA 0 2 3 1 0 2 NA NA NA 0 1 2 NA NA NA 

0:(length(a)-1) %/% 3创建所需长度的群体(在这种情况下,3)和ave用来检查是否这些组添加到0或不。

+0

是。那就是诀窍。谢谢。 – Marius 2014-09-25 09:50:35

2

要指定相同组的值,请将您的矢量转换为(三行)矩阵。然后,您可以计算列方式的总和并与0比较。其余部分很简单。

a <- c(0,0,0,0,2,3,1,0,2,0,0,0,0,1,2,0,0,0) 
a <- as.integer(a) 
is.na(a) <- rep(colSums(matrix(a, 3L)) == 0L, each = 3L) 
a 
#[1] NA NA NA 0 2 3 1 0 2 NA NA NA 0 1 2 NA NA NA 

注意,我就与整数比较表明,如果你的载体不是整数,你需要考虑this FAQ

+1

@Marius我的答案也是一行一行(实际上它比Ananda的代码短),可以使用'apply'使其更一般化。可能它也更快。 (这只是对你的评论的回复,我不需要勾号。) – Roland 2014-09-25 10:45:24

0

或者使用glaveall

n <- length(a) 
a[ave(!a, gl(n, 3, n), FUN=all)] <- NA 
a 
#[1] NA NA NA 0 2 3 1 0 2 NA NA NA 0 1 2 NA NA NA