Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy value from one column to the next given a condition

Tags:

r

I have binary data as below:

ID <- c("A", "B", "C", "D", "E", "F")
Q0 <- c(0, 0, 0, 0, 0, 0)
Q1 <- c(0, 1, 0, 0, NA, 1) 
Q2 <- c(0, NA, 1, 0, NA, 1) 
Q3 <- c(0, NA, NA, 1, NA, 1) 
Q4 <- c(0, NA, NA, 1, NA, 1)

dta <- data.frame(ID, Q0, Q1, Q2, Q3, Q4)

If there is 1 for a row in one of the columns, all the subsequent columns should be 1 as well. If there is 0 or NA, the next column should stay as is.

Stated differently, how can I change the value of multiple columns based conditionally on the value of a column in a relative position?

The intended output for the above data frame is:

ID    Q0    Q1    Q2    Q3    Q4
A     0     0     0     0     0
B     0     1     1     1     1
C     0     0     1     1     1
D     0     0     0     1     1
E     0     NA    NA    NA    NA
F     0     1     1     1     1

How can I do this? Perhaps using apply or a for loop?

like image 859
nattys Avatar asked Dec 10 '25 01:12

nattys


2 Answers

Yet another dplyr + purrr option could be:

dta %>%
 mutate(pmap_dfr(across(-ID), ~ `[<-`(c(...), seq_along(c(...)) > match(1, c(...)), 1)))

  ID Q0 Q1 Q2 Q3 Q4
1  A  0  0  0  0  0
2  B  0  1  1  1  1
3  C  0  0  1  1  1
4  D  0  0  0  1  1
5  E  0 NA NA NA NA
6  F  0  1  1  1  1
like image 114
tmfmnk Avatar answered Dec 12 '25 17:12

tmfmnk


Keeping things simple with a loop:

for (i in 3:ncol(dta)) dta[[i]][dta[[i-1]] == 1] <- 1
    #   ID Q0 Q1 Q2 Q3 Q4
    # 1  A  0  0  0  0  0
    # 2  B  0  1  1  1  1
    # 3  C  0  0  1  1  1
    # 4  D  0  0  0  1  1
    # 5  E  0 NA NA NA NA
    # 6  F  0  1  1  1  1

With dplyr + data.table inspired by Yuriy:

library(dplyr)
library(data.table)
setDT(dta)

dta[, (names(dta)[-1]) := as.list(cumany(.SD == 1)), by = ID]
like image 38
sindri_baldur Avatar answered Dec 12 '25 16:12

sindri_baldur