2015-09-04 56 views
1

这是一个微不足道的问题,但我似乎没有找到这个完美的解决方案。 (不排除NA的第一个并再次包括它们)。所以我正在寻找一些想法,而不需要NA的排除。标签开始与NA的一个序列号

我想分别用21来标记0 and 1序列的开始,并用0替换NA以及0和1的其余序列。

rle函数在这里有用吗? Base R解决方案将受到欢迎。

实施例:

x <- c(rep(NA,10),rep(1,5),rep(NA,5),rep(1,10),rep(NA,3),rep(0,7),rep(NA,15),rep(1,9)) 
r <- c(0,diff(x)); r[r %in% -1] <- 2 

从该样本数据:

x 
[1] NA NA NA NA NA NA NA NA NA NA 1 1 1 1 1 NA NA NA NA NA 1 1 1 1 1 1 1 1 1 1 NA NA NA 0 0 0 0 0 0 0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 1 1 1 1 1 1 1 1 1 

希望的输出:

[1] 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0

回答

1

我们可以使用rle创建分组变量( 'GR' )以split的'x'为list。替换为0或1 2或1使用match与第一元件,用0串联,unlist,然后用0

xN <- x 
xN[is.na(xN)] <- -999 
v1 <- rle(xN)$lengths 
gr <- rep(seq_along(v1), v1) 


x1 <- unlist(lapply(split(x, gr), function(x) 
      c(match(x[1],1:0),rep(0,length(x)-1))), use.names=FALSE) 
x1[is.na(x1)] <- 0 
x1 
#[1] 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 
#[39] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 

或代替split代替NA元素,我们可以使用whichdiff取代价值。

x1 <- (!x)+2*(!is.na(x))-1 
ind <- which(!is.na(x)) 
x1[c(ind[c(FALSE,diff(ind)==1)], which(is.na(x)))] <- 0 
x1 
#[1] 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 
#[39] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 

或者我们可以使用rleiddata.table的开发人员版本为分组变量。使用match代替0和1点的2个和1的第一元件和改变NA值为0。

library(data.table)#v1.9.5+ 
DT <- setDT(list(x)) 
DT[, c(match(V1[1], 1:0), rep(0, .N-1)) ,rleid(V1)][is.na(V1), V1:=0]$V1 
#[1] 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 
#[39] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0

将是有一个基础R溶液? (只是问问)。谢谢。 – Maximilian

+0

@Maximilian我们可以使用'rle'。 – akrun

+0

'rle'解决方案会很棒! :)任何基础R解决方案当然会做。 – Maximilian