Reputation: 41
I have a dataframe with consecutive values, is it possible to make = 0 the numbers after 1s?
df <- data.frame(a = c(0,0,0,0,1,1,1,0,0,0),
b = c(0,0,1,1,1,1,0,0,0,0),
c = c(1,1,0,0,0,0,0,1,1,0))
like this:
Upvotes: 2
Views: 102
Reputation: 17011
We keep a 1
only if it is preceded by a 0
(a 1
on the first row will always be kept). We can do this by multiplying all but the first row by the negation of all but the last row (in R, we use negative indices to exclude an index).
df[-1,] <- df[-1,]*!df[-nrow(df),]
df
#> a b c
#> 1 0 0 1
#> 2 0 0 0
#> 3 0 1 0
#> 4 0 0 0
#> 5 1 0 0
#> 6 0 0 0
#> 7 0 0 0
#> 8 0 0 1
#> 9 0 0 0
#> 10 0 0 0
Upvotes: 1
Reputation: 33548
We load data.table
for the use of shift()
.
library(data.table)
df[] <- lapply(df, \(x) replace(x, shift(x, fill = 0) == 1, 0))
df
# a b c
# 1 0 0 1
# 2 0 0 0
# 3 0 1 0
# 4 0 0 0
# 5 1 0 0
# 6 0 0 0
# 7 0 0 0
# 8 0 0 1
# 9 0 0 0
# 10 0 0 0
Upvotes: 0
Reputation: 3755
Applying diff
function may be another altarnative with BaseR
,
out <- rbind(df[1,],apply(df,2,diff))
out[out!=1] <- 0
gives,
# a b c
#1 0 0 1
#2 0 0 0
#3 0 1 0
#4 0 0 0
#5 1 0 0
#6 0 0 0
#7 0 0 0
#8 0 0 1
#9 0 0 0
#10 0 0 0
Upvotes: 2
Reputation: 52239
library(dplyr)
df %>%
mutate(across(everything(), ~ +(.x == 1 & lag(.x, default = 0) != 1)))
output
a b c
1 0 0 1
2 0 0 0
3 0 1 0
4 0 0 0
5 1 0 0
6 0 0 0
7 0 0 0
8 0 0 1
9 0 0 0
10 0 0 0
Upvotes: 2