簡體   English   中英

根據周圍的值重新編碼向量中的值

[英]Recode a value in a vector based on surrounding values

我試圖以編程方式將變量從0更改為1如果0前后有3個1 s。

例如,如果在載體中的數量為111011 ,和1 ,然后我想將改變01

這是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.

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