0
votes

Need check a column in a dataframe and replace the values if they are continuously TRUE (not continuously TRUE). Below is an example. lapply does not work, column b does not change at all.

a<- c(1,2,3,4,5,1,1,1)
b<- c(TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,FALSE,TRUE)
c<- data.frame(a,b)

index<- which(c$b == TRUE)
lapply(index,function(ind){
   c$b[ind + 1]<- ifelse(c$b[ind + 1]==TRUE,FALSE,FALSE)
})

There is another way to do it and it works good.

trues <- which(c$b)
c$b[c$b == TRUE][c(0, trues[2:length(trues)] - trues[1:length(trues)-1]) == 1] <- FALSE

The correct result is:
> c
  a     b
1 1  TRUE
2 2 FALSE
3 3 FALSE
4 4 FALSE
5 5  TRUE
6 1 FALSE
7 1 FALSE
8 1  TRUE

Still wants to know why lapply does not work! Thanks.

1
Alternatively, you can use c$b[c$b & c(1, diff(c$b)) == 0] <- FALSE for example - talat
Thanks, it is simpler! - user1047

1 Answers

2
votes

The function in lapply works like any other function in R, and has a local copy of things. Changes made in the function don't magically propagate up to the caller.

Look how c changes in this:

lapply(index, function(ind){c$a[ind]=99;print(c)})

at the end of each function call it prints c, and only one value has changed each time. Because next time in the lapply it's a new function, with a new context.

If you want things to change with lapply you have to make use of the returned value from lapply and do something with it.