if there is at least one Na in the line, make the line Na

Viewed 63

my data:

    structure(list(col1 = 1:6, col2 = c(NA, NA, 3L, 4L, 5L, 6L), 
    col3 = c(1L, 1L, NA, 1L, NA, 1L), col4 = c(2L, 2L, 2L, 2L, 
    NA, 2L), col5 = c(3L, 3L, 3L, NA, 3L, 3L), GROUP = c(1L, 
    1L, 1L, 2L, 2L, 2L)), class = "data.frame", row.names = c(NA, -6L))

I want to get a new date frame in which, if NA occurs, then replace the entire line with NA from the combination list(c(1,2),c(3,4,5)).

What I want to get:

data= structure(list(col1 = c(NA, NA, 3L, 4L, 5L, 6L), col2 = c(NA, 
NA, 3L, 4L, 5L, 6L), col3 = c(1L, 1L, NA, NA, NA, 1L), col4 = c(2L, 
2L, NA, NA, NA, 2L), col5 = c(3L, 3L, NA, NA, NA, 3L), GROUP = c(1L, 
1L, 1L, 2L, 2L, 2L)), class = "data.frame", row.names = c(NA, 
-6L))

UPDATE: I tried to do so:

list_v <- list(c(1,2),c(3,4,5))
data1 <- do.call(qpcR:::cbind.na, lapply(list_v, function(i)data[complete.cases(data[c(i)]),i]))

I need not to delete the line with Where there is at least one NA, but to replace the remaining elements with Na where there is at least one Na

1 Answers

You can do:

l <- lapply(list(c(1,2), c(3,4,5)), \(i) df[, i])

cbind.data.frame(lapply(l, \(y) t(apply(y, 1, \(x) {
  if(any(is.na(x))) x[1:length(x)] <- NA
  x
}))))

#  col1 col2 col3 col4 col5
#1   NA   NA    1    2    3
#2   NA   NA    1    2    3
#3    3    3   NA   NA   NA
#4    4    4   NA   NA   NA
#5    5    5   NA   NA   NA
#6    6    6    1    2    3

Using apply and an if else statement, you can do:

t(apply(df, 1, function(x){
  if(any(is.na(x[1:2])))
    x[1:2] <- NA
  else if(any(is.na(x[3:5])))
    x[3:5] <- NA
  x
}))

#     col1 col2 col3 col4 col5 GROUP
#[1,]   NA   NA    1    2    3     1
#[2,]   NA   NA    1    2    3     1
#[3,]    3    3   NA   NA   NA     1
#[4,]    4    4   NA   NA   NA     2
#[5,]    5    5   NA   NA   NA     2
#[6,]    6    6    1    2    3     2

Here, apply repeats a function (defined in the third parameter) on each rows (MARGIN = 1) of df.

Related