删除向量中的重复项但保留顺序

时间:2014-01-23 08:43:50

标签: r vector

假设一个向量:

vec = c(NA,NA,1,NA,NA,NA,1,NA,NA,0,NA,NA,0,NA,NA,0,NA,NA,1,NA,NA,1,NA,NA,0,NA,0)

我想得到:

vec = c(NA,NA,1,NA,NA,NA,NA,NA,NA,0,NA,NA,NA,NA,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,0,NA,NA)

我尝试了一个for循环,if if检查该值是否等于之前的非NA,但是当它重复多次时它不起作用。

Remove duplicates in vector to next value 因为我想保留我的NAs,所以也不起作用。

3 个答案:

答案 0 :(得分:4)

使用duplicated

vec[duplicated(vec, incomparables=NA)] <- NA

您可以省略示例中的incomparables参数:

vec[duplicated(vec)] <- NA

根据文档,这可能会更快,但您需要自己进行基准测试。

修改

澄清之后:

vec <- c(NA,NA,1,NA,NA,NA,1,NA,NA,NA,NA,0,NA,NA,0,NA,NA,0,NA,NA,NA,1,NA,NA,1,NA,NA,0,NA,0)
vec2 <- c(NA,NA,1,NA,NA,NA,NA,NA,NA,NA,NA,0,NA,NA,NA,NA,NA,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,0,NA,NA)

tmp <- vec[!is.na(vec)]
tmp[c(FALSE, diff(tmp)==0)] <- NA
vec[!is.na(vec)] <- tmp

identical(vec, vec2)
#[1] TRUE

答案 1 :(得分:4)

您可以通过一些逻辑和复合[[<-操作来完成此操作。首先,我们需要找到重复项。我们将对所有非diff()NA执行此操作...

diff( vec[ ! is.na( vec ) ]
[1]  0 -1  0  0  1  0 -1  0

每个0都是重复的。现在我们需要在vec中找到他们的位置并将其设置为NA ..

#  This gives us a vector of TRUE/FALSE values which we will use to subset vec to the values we want to change
dups <- c( 1 , diff( vec[ ! is.na( vec ) ] ) ) == 0

#  Now subset vec to non NA values and change the duplicates to NA
vec[ ! is.na( vec ) ][ dups ] <- NA
# [1] NA NA  1 NA NA NA NA NA NA NA NA  0 NA NA NA NA NA NA NA NA NA  1 NA NA NA
#[26] NA NA  0 NA NA

答案 2 :(得分:3)

我认为这样做:

vrl<-rle(vec)
diff(vrl$values[!is.na(vrl$values)])->vdif
vdif<-c(1,vdif)
vrl$values[!is.na(vrl$values)][vdif==0]<-NA
inverse.rle(vrl)
# [1] NA NA  1 NA NA NA NA NA NA  0 NA NA NA NA NA NA NA NA
#[19]  1 NA NA NA NA NA  0 NA NA

其中的技巧是在差异向量前加1,以便保留第一个非NA位置。