0

I have vector of strings containing numbers. Within these strings, I would like to remove all access zeros behind the decimal separator. So I tried mutate_all(funs(str_replace(., ".00", ""))).

This works for the first number in my vector: v <- c("bla 500.00", "bla 1.20", "bla 1.10", "bla 2.34").

For the rest I would not like to hard code mutate_all(funs(str_replace(., ".10", ".1")))%>%mutate_all(funs(str_replace(., ".20", ".2")))%>% ..., but use some kind of smart regex, which automatically does the job. So, removing every zero which is behind ".non-zero-integer" (dot non-zero-integer), while keeping the ".non-zero-integer" the same.

MsGISRocker
  • 588
  • 4
  • 21

3 Answers3

3

You could try to find:

\b(\d+)(?:\.0+|(\.\d+?))0*\b

And replace with \1\2. See an online demo


  • \b - Word-boundary;
  • (\d+) - Capture trailing digits upto;
  • (?: - Open a non-capture group;
    • \.0+ - 1+ zero's;
    • | - Or;
    • (\.\d+?) - A nested 2nd capture group to match a dot followed by a digit and 0+ (lazy) digits;
    • ) - Close non-capture group;
  • 0* - 0+ (greedy) digits;
  • \b - Trailing word-boundary.

library(stringr)
v <- c("bla 500.00", "bla 1.20", "bla 1.10", "bla 2.34", "bla 2.340003", "bla 1.032", "bla 1.10 bla 2.00")
v <- str_replace_all(v, "\\b(\\d+)(?:\\.0+|(\\.\\d+?))0*\\b", "\\1\\2")
v

Prints: "bla 500", "bla 1.2", "bla 1.1", "bla 2.34", "bla 2.340003", "bla 1.032", "bla 1.1 bla 2"

JvdV
  • 70,606
  • 8
  • 39
  • 70
2

How about this base R solution:

v <- c("bla 500.00", "bla 1.20", "bla 1.10", "bla 2.34")
v <- gsub("(.*[\\.1-9])0*$", "\\1", v)
v <- gsub("\\.$", "", v)
v
#> [1] "bla 500"  "bla 1.2"  "bla 1.1"  "bla 2.34"

Created on 2022-07-13 by the reprex package (v2.0.1) The first gsub() function removes trailing zeros and the second gsub() removes the period if it is at the end of the number, so it changes 500. into 500

DaveArmstrong
  • 18,377
  • 2
  • 13
  • 25
0

You can do this. Note that mutate_all has been superseded by mutate(across()) (see the docs).

v <- c("bla 500.00", "bla 1.20", "bla 1.10", "bla 2.34")
dat  <- data.frame(v = v)

dat  |>
    mutate(
        across(v, \(x) stringr::str_replace(x, "\\.\\d{2}", ""))
    )

#         v
# 1 bla 500
# 2   bla 1
# 3   bla 1
# 4   bla 2

Base R

gsub("\\.\\d{2}", "", dat$v)
# "bla 500" "bla 1"   "bla 1"   "bla 2"
SamR
  • 8,826
  • 3
  • 11
  • 33