2016-11-01 23 views
2

我是否錯過了這樣做的更好方法 - 或者至少允許改變窗口大小的方法?尋找值是否存在於向量r的前n個值中

說我有一個向量,訴

v <- c(T,T,F,F,F,F,F,T,T,T,T,F,F,F,F,T,F,F,F,F,F,F,T,F) 

我希望這個載體,使得FALSEs被翻到TRUEs如果真出現以前的3元內轉換。例如位置3,4,5處的F也會切換到T,因爲在位置2處有T.位置6處的F不會。

解決方案,如果只關心3個窗口:

vlag1 <- lag(v) 
vlag2 <- lag(vlag1) 
vlag3 <- lag(vlag2) 
ifelse(v==T|vlag1==T|vlag2==T|vlag3==T,T,F) 

得到期望的結果:

TRUE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE TRUE 

但是,如果我們想改變窗口例如4或5 - 有更好的方法嗎?

+0

的OP的輸出'如果你要堅持立足R. – joran

+0

@joran embed'可能是有用的一個選擇 - 是的謝謝,基地R是首選 – jalapic

+0

@亨利克 - 感謝這是一個很好的捕獲。上面的'ifelse'似乎給出了我給出的預期結果,就像'zoo'和'base'解決方案一樣。在這種情況下'data.table'解決方案不起作用。我非常感謝你注意到這一點。 – jalapic

回答

0

您可以用rollapplyzoo包做到這一點:

library(zoo) 

rollapply(v, 
      width = 4, align = "right", partial = TRUE, 
      FUN = function(x) ifelse(TRUE %in% x, TRUE, FALSE)) 

請注意,我已經設置width = 4這裏,不是3.在你的問題,你說你想檢查以前的3個元素。寬度包括第i個元素。因此,如果您想將結果基於前3個,則必須將寬度設置爲4.還需要包含align = "right"以從第i個元素(默認中心位於第i個元素上)回顧,還可以向前看與align = "left")。

+1

或'rollapplyr(v,4,any,partial = TRUE)' –

0

這是一個更手動解決方案:

# Input vector 
v <- c(T,T,F,F,F,F,F,T,T,T,T,F,F,F,F,T,F,F,F,F,F,F,T,F) 

# Size of the window 
k <- 3 

# Output vector 
outp <- rep(F,length(v)) 

for(i in seq(length(v))){ 
    # Checking values on variable window 
    aux <- v[seq(pmax(1,i-k),i)] 
    # Writing on output vector 
    outp[i] <- any(aux==T) 
} 

outp 
0

這裏是data.table

library(data.table) 
n <- 3 
r1 <- Reduce(`|`, shift(v, seq_len(n), fill = FALSE)) 
identical(r1, r2) 
#[1] TRUE 

其中 'R2' 是ifelse