Luks
Luks

Reputation: 143

Replace consecutive repeated values with NA in list

I would like to replace consecutively repeated values that are stored in dataframes within lists with NA, see the example below:

A = data.frame(matrix( 
c(1, 2, 3, 1, 1, 3, 3, 1), 
  nrow=4, 
  ncol=2))

B = data.frame(matrix( 
  c(1, 1, 2, 1, 1, 2, 3, 1), 
  nrow=4, 
  ncol=2))

myList <- list(A,B)

giving:

[[1]]
  X1 X2
1  1  1
2  2  3
3  3  3
4  1  1

[[2]]
  X1 X2
1  1  1
2  1  2
3  2  3
4  1  1

And I am aiming for

[[1]]
  X1 X2
1  1  1
2  2  3
3  3  NA
4  1  1

[[2]]
  X1 X2
1  1  1
2  NA 2
3  2  3
4  1  1

I imagine this should be relatively straight forward with lapply, but I simply do not get there..

Upvotes: 3

Views: 319

Answers (2)

missuse
missuse

Reputation: 19716

Here is an approach using lag function from library(dplyr)

library(dplyr)

  lapply(myList, function(x){
      b = apply(x, 2, function(y){
        c(y[1],ifelse(y == lag(y), NA, y)[2:length(y)])
         })
      return(as.data.frame(b))
    })

so if y is the same as lag(y) return NA, else return y. But not for the first element of y since lag(y[1]) is NA.

Upvotes: 3

zx8754
zx8754

Reputation: 56169

Using diff:

res <- lapply(myList, function(i)
  data.frame(lapply(i, function(j)
    ifelse(c(FALSE, diff(j) == 0), NA, j)
  )))

res
# [[1]]
#   X1 X2
# 1  1  1
# 2  2  3
# 3  3 NA
# 4  1  1
# 
# [[2]]
#   X1 X2
# 1  1  1
# 2 NA  2
# 3  2  3
# 4  1  1

Upvotes: 3

Related Questions