2

How do I count trailing zeros in a vector of string. For example, if my vector of string is:

x = c('0000','1200','1301','X230','9900')

The answer should be

> numZeros
[1] 4 2 0 1 2

I do not want to use multiple ifelse as I think a more elegant and faster solution should be present. I tried using modulus, like this

y = as.integer(x)
numZeros = (!(y%%10000))+(!(y%%1000))+(!(y%%100))+(!(y%%10))

but that would require two conditions to be true.

  • Maximum length of the string is fixed (which is true in my case) and
  • All the strings in the vector are convertible to integers, which is not true in my case.

Then used stringr package and created a solution but it is very lengthy.

library(stringr)
numZeros = 
4*str_detect(x,"0000") + 
3*str_detect(x,"[1-9 A-Z]000") + 
2*str_detect(x,"[1-9 A-Z]{2}00") + 
str_detect(x,"[1-9 A-Z]{3}0")

Also, I can't figure out whether str_detect uses ifelse by looking at definition of str_detect.

I found same question here but for python. If this has been answered for R, please provide the link.

Gaurav Singhal
  • 998
  • 2
  • 10
  • 25

3 Answers3

6

I found a simple solution with base R:

x <- c('0000','1200','1301','X230','9900')
nchar(x) - nchar(sub("0*$", "", x))
# > nchar(x) - nchar(sub("0*$", "", x))
# [1] 4 2 0 1 2
jogo
  • 12,469
  • 11
  • 37
  • 42
4

We can use str_extract to extract one or more 0's at the end ($) of the string and use nchar to get the count. If needed, assign the NA elements to 0

library(stringr)
res <- nchar(str_extract(x, "0+$"))
res[is.na(res)] <- 0
res
#[1] 4 2 0 1 2

data

x = c('0000','1200','1301','X230','9900')
akrun
  • 874,273
  • 37
  • 540
  • 662
3

You may match all trailing 0s and then count them. Here is a base R solution:

> matches <- regmatches(x, gregexpr("0(?=0*$)", x, perl=TRUE))
> sapply(matches, length)
[1] 4 2 0 1 2

Here, 0(?=0*$) matches any 0 that is only followed with zero or more (*) zeros at the end of the string ($).

See this regex demo and an R demo online.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563