Reputation: 662
I have a data frame which contains some values. And now I would like to keep only the max value in each row and give 0 to the rest column, like this:
df <- data_frame(a= c(1,2,3,4,5),b= c(2,5,3,9,7),c= c(40,6,2,1,7))
df$rowmax <- apply(df,1,max)
#
a b c rowmax
<dbl> <dbl> <dbl> <dbl>
1 2 40 40
2 5 6 6
3 3 2 3
4 9 1 9
5 7 7 7
#ideal out put
a b c rowmax
0 0 40 40
0 0 6 6
3 3 0 3
0 9 0 9
0 7 7 7
Could any one help me out here? thanks ; )
Upvotes: 2
Views: 191
Reputation: 14774
A base
option:
sweep(df, 1, apply(df, 1, max), FUN = function(x, y) x * (x == y))
Output:
a b c
1 0 0 40
2 0 0 6
3 3 3 0
4 0 9 0
5 0 7 7
Upvotes: 2
Reputation: 887891
It may be more efficient to use pmax
to get the row wise max
, then select the columns of interset in mutate_at
and replace
the values in each column not equal to 0
library(dplyr)
library(purrr)
df %>%
mutate(rowmax = reduce(., pmax)) %>%
#or as @tmfmnk mentioned in the comments
# mutate(rowmax = exec(pmax, !!!.)) %>%
mutate_at(vars(a:c), ~ replace(., .!= rowmax, 0))
#Or do a multiplication
#mutate_at(vars(a:c), ~. * (.== rowmax))
Also, if we don't need the rowmax
column, a base R
option is
df * (df == do.call(pmax, df))
Upvotes: 3