[英]Create a list of vectors from a vector where n consecutive values are not 0 in R
[英]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.locf0
與maxgap
來填補它,將它添加到原來的載體,適用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,}
。
另一種使用ave
和head
和tail
來比較連續值的基本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.