Pluto Liu
Pluto Liu

Reputation: 27

expand numbers with text separated by hyphen R

Following the question here

How to expand a given range of numbers to include all numbers separated by a dash

It worked well with "text+ number range", like in the example "Ballroom 1-3"

The code is this

expand.dash <- function(dashed) {
  limits <- as.numeric(unlist(strsplit(dashed, '-')))
  seq(limits[1], limits[2])
}

expand.ballrooms <- function(txt) {
  str <- gsub('\\d+\\s?-\\s?\\d+', '%d', txt)
  dashed_str <- gsub('[a-zA-Z ]+', '', txt)
  sprintf(str, expand.dash(dashed_str))
}

>expand.ballrooms("Ballroom 1-3")
#[1] "Ballroom 1" "Ballroom 2" "Ballroom 3"

>expand.ballrooms("Ballroom 1 - 3")
#[1] "Ballroom 1" "Ballroom 2" "Ballroom 3"

But if there is "text+number - text+number", for example "Ballroom1 - Ballroom3" The original code doesn't work well, and returns

[1] "Ballroom1 - Ballroom3" "Ballroom1 - Ballroom3" "Ballroom1 - Ballroom3"

And I reckon would need to change this line

str <- gsub('\\d+-\\d+', '%d', txt)

But I can't really figure out how it could work.

The result should still be "Ballroom 1" "Ballroom 2" "Ballroom 3".

Thank you!

Upvotes: 0

Views: 441

Answers (4)

hello_friend
hello_friend

Reputation: 5788

Base R solution:

test1 <- "Ballroom 1 - 3"
test2 <- "Ballroom1 - Ballroom3"
expand.ballrooms <- function(string_to_expand){
  y <- unlist(strsplit(string_to_expand, "\\s*\\-\\s*"))
  prefix <- Filter(function(z){z!=""}, trimws(gsub("(\\d+)|\\-", "", y)))
  nos <- trimws(gsub("\\D+", "", y))
  res <- paste(prefix, eval(parse(text=paste0(nos, collapse = ":"))))
  return(res)
}
expand.ballrooms(test1)
expand.ballrooms(test2)

Upvotes: 0

Sirius
Sirius

Reputation: 5429

This should cover just about everything:


expand.ballroom <- function(x) {
    m <- str_match( x, "Ballroom *(\\d+) *- *(?:Ballroom)? *(\\d+)" )
    return( paste( "Ballroom", m[,2]:m[,3] ) )
}

expand.ballroom( "Ballroom1 - Ballroom3" )
expand.ballroom( "Ballroom 1 - Ballroom 3" )
expand.ballroom( "Ballroom 1-3" )
expand.ballroom( "Ballroom1-3" )
expand.ballroom( "Ballroom 1 - 3" )

It produces:


> expand.ballroom( "Ballroom1 - Ballroom3" )
[1] "Ballroom 1" "Ballroom 2" "Ballroom 3"

> expand.ballroom( "Ballroom 1 - Ballroom 3" )
[1] "Ballroom 1" "Ballroom 2" "Ballroom 3"

> expand.ballroom( "Ballroom 1-3" )
[1] "Ballroom 1" "Ballroom 2" "Ballroom 3"

> expand.ballroom( "Ballroom1-3" )
[1] "Ballroom 1" "Ballroom 2" "Ballroom 3"

> expand.ballroom( "Ballroom 1 - 3" )
[1] "Ballroom 1" "Ballroom 2" "Ballroom 3"

Upvotes: 0

norie
norie

Reputation: 9857

This will extract the first word, e.g. Ballroom from the string, and the digits.

expand.dash <- function(dashed) {
  limits <- as.numeric(unlist(strsplit(dashed, '-')))
  seq(limits[1], limits[2])
}

expand.ballrooms <- function(txt) {
  str <- paste0(gsub("([A-Za-z]+).*", "\\1", txt), "%d")
  dashed_str <- gsub('[a-zA-Z ]+', '', txt)
  sprintf(str, expand.dash(dashed_str))
}

> expand.ballrooms("Ballroom 1-3")
[1] "Ballroom1" "Ballroom2" "Ballroom3"
> expand.ballrooms("Ballroom 1 - 3")
[1] "Ballroom1" "Ballroom2" "Ballroom3"
> expand.ballrooms("Ballroom1 - Ballroom3")
[1] "Ballroom1" "Ballroom2" "Ballroom3"

Upvotes: 0

Rui Barradas
Rui Barradas

Reputation: 76450

Here is a base R way.

x <- "Ballroom1 - Ballroom3"

y <- gsub("[^[:digit:]\\-]", "", x)
expand.ballrooms(paste("Ballrooms", y))
#[1] "Ballrooms 1" "Ballrooms 2" "Ballrooms 3"

Upvotes: 1

Related Questions