簡體   English   中英

如何從矢量或列表中消除n個連續值?

[英]How do I eliminate n-consecutive values from a vector or a list?

假設我有:

v <- c(1,2,0,0,0,3,4,4,4,0,0,0,0,5,0)
v
 [1] 1 2 0 0 0 3 4 4 4 0 0 0 0 5 0

我想消除任何連續的0,其中連續0的數量是2+(2或更多)。 所以上面的例子會變成:

1 2 3 4 4 4 5 0

注意:我更喜歡base-R解決方案,但其他解決方案會很有趣

1)na.locf0這使用了zoo包,但只有一行代碼。 它利用的maxgap在爭論na.locf0 替換每個0與NA以及其他一切與0。使用na.locf0maxgap來填補它,將它添加到原來的載體,適用na.omit除去NAS與使用c刪除屬性。

library(zoo)

c(na.omit(na.locf0(ifelse(v == 0, NA, 0), maxgap = 1) + v))
## [1] 1 2 3 4 4 4 5 0

2)RLEID這使用rleid從data.table。 它比(1)略長,但仍然相當短。 它使用rleid對數據進行rleid ,然后為每個組生成一個NA或原始數據,最后刪除NA。

library(data.table)

fun <- function(x) if (x[1] == 0 & length(x) > 1) NA else x
c(na.omit(ave(v, rleid(v), FUN = fun)))
## [1] 1 2 3 4 4 4 5 0

rle選項。 我們可以用rle創建一個邏輯條件,並根據它提取values

with(rle(v), {i1 <- !(values == 0 & lengths > 1); rep(values[i1], lengths[i1])})
#[1] 1 2 3 4 4 4 5 0

注意:在先前版本中,OP'輸出僅返回單個value 我們只需要使用相同的邏輯來rep lengths


或者它可以通過rleid更緊湊

library(data.table)
v[!(ave(v, rleid(v), FUN = length) > 1 & !v)]
#[1] 1 2 3 4 4 4 5 0

這里有一個中的解決方案base

as.numeric(unlist(strsplit(gsub("(0\\,){2,}","",paste0(v,collapse=",")),",")))

 # [1] 1 2 3 4 4 4 5 0

NB在你的問題中,你說連續0的數量是2+ ,但你的例子是3 +連續的零; 如果需要{2,}{2,}更改為{3,}

另一種使用aveheadtail來比較連續值的基本R方式

v[!ave(v == 0, cumsum(c(TRUE, head(v, -1) != tail(v, -1))), 
               FUN = function(x) all(x) & length(x) >= 2)]

#[1] 1 2 3 4 4 4 5 0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM