4

Using dplyr, is there a way to selectively mutate columns by row without using rowwise()?

For example, given input below, I want to replace negative numbers with zeroes in columns prefixed with "pre_":

df <- data.frame(a=c(-5, 3, 4, 5), b=4:1, pre_c=c(-1, -5, 3, 10), pre_d=c(-6, 5, -12, 0))
#    a b pre_c pre_d
# 1 -5 4    -1    -6
# 2  3 3    -5     5
# 3  4 2     3   -12
# 4  5 1    10     0

My desired output is:

#    a b pre_c pre_d
# 1 -5 4     0     0
# 2  3 3     0     5
# 3  4 2     3     0
# 4  5 1    10     0

This can be acheived with rowwise() and mutate_at():

df %>% 
   rowwise() %>% 
   mutate_at(vars(starts_with("pre_")), funs(max(0, .)))

Is there another way to do this?

Megatron
  • 15,909
  • 12
  • 89
  • 97

2 Answers2

4

You could use pmax (or replace) without rowwise

library(dplyr)
df %>% 
  mutate_at(vars(starts_with("pre_")), list(~pmax(0, .)))
   a b pre_c pre_d
1 -5 4     0     0
2  3 3     0     5
3  4 2     3     0
4  5 1    10     0

Using base R

df[startsWith(names(df), "pre_")][df[startsWith(names(df), "pre_")] < 0] <- 0
markus
  • 25,843
  • 5
  • 39
  • 58
0

You can also try:

df %>%
 mutate_at(vars(starts_with("pre_")), list(~ (. > 0) * .))

   a b pre_c pre_d
1 -5 4     0     0
2  3 3     0     5
3  4 2     3     0
4  5 1    10     0
tmfmnk
  • 38,881
  • 4
  • 47
  • 67