0

I have a tibble (dataframe) and I would like to select numeric elements greater than some number (e.g., 20) and update them to a new value (e.g., 0) like this:

mtcars_tbl <- as_tibble(rownames_to_column(mtcars))
mtcars_tbl[mtcars_tbl > 20] <- 0

However this also updates my rownames column which is a character variable that I want to preserve. Normally I would store my rownames in the rownames attribute of my dataframe. But tibbles don't support rownames anymore - which is a little annoying. Is there some other obvious solution I'm missing (apart from converting my data to a data.frame and back to a tibble)?

sometimes_sci
  • 183
  • 1
  • 10
  • 2
    rownames are technically still there `x <- as_tibble(mtcars); x[x > 20] <- 0; print.data.frame(x)` – rawr Mar 13 '18 at 00:15
  • yes, with your code snippet that is true. But if I've already lost the rownames (because I've selected something in the tibble earlier) then rownames are converted to sequential numbers and the original rownames are lost... – sometimes_sci Mar 13 '18 at 01:13

1 Answers1

1

Instead of applying the replacement across the entire tibble, you could make it conditional on a predicate, like is.numeric.

library(dplyr)
library(tibble)

mtcars_tbl <- as_tibble(rownames_to_column(mtcars))

mtcars_tbl %>%
  mutate_if(is.numeric, ~{if_else(. > 20, 0, .)})

# # A tibble: 32 x 12
#    rowname             mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
#    <chr>             <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#  1 Mazda RX4           0.     6.    0.    0.  3.90  2.62  16.5    0.    1.    4.    4.
#  2 Mazda RX4 Wag       0.     6.    0.    0.  3.90  2.88  17.0    0.    1.    4.    4.
#  3 Datsun 710          0.     4.    0.    0.  3.85  2.32  18.6    1.    1.    4.    1.
#  4 Hornet 4 Drive      0.     6.    0.    0.  3.08  3.22  19.4    1.    0.    3.    1.
#  5 Hornet Sportabout  18.7    8.    0.    0.  3.15  3.44  17.0    0.    0.    3.    2.
#  6 Valiant            18.1    6.    0.    0.  2.76  3.46   0.     1.    0.    3.    1.
#  7 Duster 360         14.3    8.    0.    0.  3.21  3.57  15.8    0.    0.    3.    4.
#  8 Merc 240D           0.     4.    0.    0.  3.69  3.19  20.0    1.    0.    4.    2.
#  9 Merc 230            0.     4.    0.    0.  3.92  3.15   0.     1.    0.    4.    2.
# 10 Merc 280           19.2    6.    0.    0.  3.92  3.44  18.3    1.    0.    4.    4.
# # ... with 22 more rows
Kevin Arseneau
  • 6,186
  • 1
  • 21
  • 40