[英]Recode a value in a vector based on surrounding values
我試圖以編程方式將變量從0
更改為1
如果0
前后有3個1
s。
例如,如果在載體中的數量為1
, 1
, 1
, 0
, 1
, 1
,和1
,然后我想將改變0
到1
。
這是data.frame
df
向量dummy_code
中的data.frame
:
original_df <- data.frame(dummy_code = c(1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1))
這是我嘗試重新編碼值的方式:
desired_df <- data.frame(dummy_code = c(1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1)
我嘗試在tidyr
包中使用函數fill
,但這會填充缺少的值,因此將無法正常工作。 如果我要重新編碼要丟失的0
值,那也將不起作用,因為當我只想將被三個1s
包圍的每個NA
編碼為1
時,它只會將每個NA
編碼為1
。
有沒有辦法以編程方式有效地做到這一點?
這是動物園使用rollapply
:
library(zoo)
rollapply(c(0, 0, 0, x, 0, 0, 0), 7, function(x) if (all(x[-4] == 1)) 1 else x[4])
## [1] 1 0 0 1 1 1 1 1 1 1 0 0 1
注意:使用的輸入為:
x <- c(1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1)
一個rle
替代方案中,使用x
從@G。 格洛騰迪克的答案:
r <- rle(x)
查找三個1
的運行索引:
i1 <- which(r$lengths == 3 & r$values == 1)
檢查包圍0
的“ 1
索引”中的哪個,並獲取要替換的0
的索引:
i2 <- i1[which(diff(i1) == 2)] + 1
將相關的0
替換為1
:
r$values[i2] <- 1
在更新的運行中反轉rle
操作:
inverse.rle(r)
# [1] 1 0 0 1 1 1 1 1 1 1 0 0 1
基於data.table::rleid
類似解決方案,稍微緊湊一些,也許更易於閱讀:
library(data.table)
d <- data.table(x)
計算每次運行的長度:
d[ , n := .N, by = rleid(x)]
為“×”,它們是零和前述和隨后的運行1
是長度的3
,設置“X”到1
:
d[x == 0 & shift(n) == 3 & shift(n, type = "lead") == 3, x := 1]
d$x
# [1] 1 0 0 1 1 1 1 1 1 1 0 0 1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.