kittygirl
kittygirl

Reputation: 2443

How to keep only max value of row and convert other value to NA?

df <- data.frame(
  cola = c(3,NA,NA,NA,1,5),
  colb = c(7,NA,NA,NA,NA,6),
  colc = c(NA, NA, 10, NA, NA, 6)
)

Use above data.frame as example,I want to keep the max value of each row, and convert other value to NA,which means convert origin data.frame

cola colb colc
   3    7   NA
  NA   NA   NA
  NA   NA   10
  NA   NA   NA
   1   NA   NA
   5    6   6

to expect result as below:

cola colb colc
NA    7   NA
NA   NA   NA
NA   NA   10
NA   NA   NA
1   NA   NA
NA    6   6

How to do it?

Upvotes: 1

Views: 286

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 389275

You can use purrr::pmap_df

purrr::pmap_df(df, ~{
      vec <- c(...)
      ifelse(vec != max(vec, na.rm = TRUE), NA, vec)
})

# A tibble: 6 x 3
#   cola  colb  colc
#  <dbl> <dbl> <dbl>
#1    NA     7    NA
#2    NA    NA    NA
#3    NA    NA    10
#4    NA    NA    NA
#5     1    NA    NA
#6    NA     6     6

Upvotes: 0

akrun
akrun

Reputation: 887901

We can use apply to loop over the rows (MARGIN = 1) and replace the values that are not equal to max with NA, assign the transpose back to the original object

df[] <- t(apply(df, 1, function(x) replace(x, x != max(x, na.rm = TRUE), NA)))

Or with rowMaxs

library(matrixStats)
i1 <- !!rowSums(!is.na(df))
df[i1,] <-  replace(df[i1,], df[i1,] != rowMaxs(as.matrix(df[i1,]), 
                na.rm = TRUE)[col(df[i1,])], NA)

Or using dplyr

library(dplyr)
library(purrr)
df %>% 
  mutate(new = reduce(., pmax, na.rm = TRUE)) %>% 
  transmute_at(vars(starts_with('col')), ~ replace(., .!= new, NA))

Upvotes: 1

Related Questions