R:改变特定值的最后一个序列



我有一个包含0和1列的数据框架。我想把最后一个1序列变成0,像这样:

# data

a <- c(0,1,1,0,1,1,1)
b <- c(0,1,1,1,0,1,1)
c <- data.frame(cbind(a,b))
head(c,7)
# desired output
a_desired <- c(0,1,1,0,0,0,0)
b_desired <- c(0,1,1,1,0,0,0)
c_desired <- data.frame(cbind(a_desired,b_desired))
head(c_desired,7)

使得我最终得到相同的序列,除了最后的1序列已经突变为0。我试过使用tail(),但到目前为止还没有找到解决方案

您可以尝试使用rle

apply(c, 2, function(x){
y <- max(which(rle(x == 1)$values))
x[(sum(rle(x == 1)$lengths[1:(y-1)]) + 1): sum(rle(x == 1)$lengths[1:y])] <- 0
x
})
a b
[1,] 0 0
[2,] 1 1
[3,] 1 1
[4,] 0 1
[5,] 0 0
[6,] 0 0
[7,] 0 0

purrr::map变型

library(purrr)
map(c, function(x){

last1 <- max(which(x == 1))
last0 <- which(x[1:last1] == 0)

c(x[seq_len(max(last0))], rep(0, length(x) - max(last0))) 
})

您可以尝试cumsumx == 0的组合,并替换等于max的值。

sapply(c, function(x) {
. <- cumsum(diff(c(0,x)==1)==1)
`[<-`(x, . == max(.), 0L)
#replace(x, . == max(.), 0L) #Alternaive to [<-
})
#     a b
#[1,] 0 0
#[2,] 1 1
#[3,] 1 1
#[4,] 0 1
#[5,] 0 0
#[6,] 0 0
#[7,] 0 0

或者相同,但以不同的方式写(感谢@thelatemail))

sapply(c, function(x) {
cs <- cumsum(diff(c(0,x)==1)==1)
x[cs == max(cs)] <- 0L
x
})

或者从最后一个元素开始迭代,直到找到0为止。

sapply(c, function(x) {
n <- length(x)
i <- n
while(x[i] != 1 & i>1L) i <- i-1L
while(x[i] != 0 & i>1L) i <- i-1L
x[i:n] <- 0L
x  
})

您可以自己编写函数:

fun <- function(x){
y <- rle(x)
y$values[length(y$values)] <- 0
inverse.rle(y)
}

现在运行:

data.frame(sapply(c, fun))
a b
1 0 0
2 1 1
3 1 1
4 0 1
5 0 0
6 0 0
7 0 0

如果你的序列总是以1s结束,你可以尝试(给定df <- data.frame(a,b))

> df * sapply(df, function(x) rev(cumsum(rev(x != 1)) != 0))
a b
1 0 0
2 1 1
3 1 1
4 0 1
5 0 0
6 0 0
7 0 0

相关内容

  • 没有找到相关文章

最新更新