1

In R trying to write a function that takes the word MarsuPial and results in marsupiaL.

current code

mycap <- function(mystr = "") {
  mystr <- tolower(mystr)
  a <- substr(mystr, 1, 1)
  b <- substr(mystr, 2, nchar(mystr))
  paste(tolower(a), b, sep = "")
}
putnro01
  • 21
  • 3
  • 1
    some other options `gsub('(.*)(.)$', '\\L\\1\\U\\2', 'MarsuPial', perl = TRUE)` or `gsub('(.)$', '\\U\\1', tolower('MarsuPial'), perl = TRUE)` – rawr Aug 04 '20 at 02:16
  • @rawr I like your solution - `myCap <- function(x) sub('(.*)(.)$', '\\L\\1\\U\\2', x, perl = TRUE)` seems to be the fastest of the bunch (not that it would matter in most cases) – user12728748 Aug 04 '20 at 02:35

3 Answers3

1

You can use substr<- to capitalise the last character.

mycap <- function(mystr = "") {
  mystr <- tolower(mystr)
  n <- nchar(mystr)
  substr(mystr, n, n) <- toupper(substr(mystr, n, n))
  return(mystr)
}

mycap('MarsuPial')
#[1] "marsupiaL"
mycap('dummy')
#[1] "dummY"
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
1
mycap <- function(mystr = "") {
  # a: the string without the last character
  a <- substr(mystr, 1, nchar(mystr)-1)

  # b: only the last character 
  b <- substr(mystr, nchar(mystr), nchar(mystr))

  # lower(a) and upper(b)
  paste(tolower(a), toupper(b), sep = "")
}

For your example:

mycap("MarsuPial")
[1] "marsupiaL
Aziz
  • 20,065
  • 8
  • 63
  • 69
1

Another option avoiding string subsetting/splitting is to convert the string to an integer vector to reverse the order so that we can use stringr::str_to_title.

library(stringr)
library(dplyr)
mycap <- function(mystr = "") {
    mystr %>% utf8ToInt %>% rev %>% intToUtf8 %>% str_to_title %>% utf8ToInt %>% rev %>% intToUtf8
}

mycap("MarsuPial")
#[1] "marsupiaL"
mycap("dummy")
#[1] "dummY"

Or another fast option is to use stringi::stri_reverse and stringi::stri_trans_totitle

library(stringi)
mycap <- function(mystr = "") stri_reverse(stri_trans_totitle(stri_reverse(mystr)))
Maurits Evers
  • 49,617
  • 4
  • 47
  • 68