rfunction

Converting character vectors to the same units of measure


Problem: I have a character vector that is a mix of foot/inchs, m and cm. I am trying to convert them all to cm.

Vector looks something like this:

Height <- c("165", "185", "5'1", "1.88")

Converting the "5'1" was easy (found this piece of code on stackoverlow):

 ft_cm <- function (str_ft_inch) {
   elem <- as.integer(unlist(strsplit(str_ft_inch, "'")))
   inch <- elem[1] * 12 + elem[2]
   return(conv_unit(inch, "inch", "cm")) }

Height_converted <- sapply(Height, ft_cm) 
> 165 185  5'1   1.88
  NA  NA  154.94 NA

Now I want to replicate this for the metre "1.88". I have recycled the ft_cm function. This is the new function:

m_cm <- function (str_m_cm) {
   elem <- as.integer(unlist(strsplit(str_m_cm, ".")))
   cm <- elem[1] * 100 + elem[2]
return(cm)
}

Height_m_to_cm <- sapply(Height, m_cm)
> 165 185 5'1 1.88
  NA  NA  NA  NA

I want my desired outcome to be:

Height_converted
> 165 185 5'1    1.88
  165 185 154.94 188

I'm not sure why it is having trouble with this. Any help would be appreciated. P.S. This was only a snippet of a much longer character vector.


Solution

  • I think you can just sub the . away (assuming you always have two digits after the decimal point as shown), then grepl for feet, and convert these.

    > cnv_unts <- \(x) {
    +   x <- sub('\\.', '', x)
    +   ft <- grepl('\'', x)
    +   x[ft] <- strsplit(x[ft], '\'') |> lapply(type.convert, as.is=TRUE) |>
    +     sapply(\(.) sum(.*c(12, 1))*2.54)
    +   as.numeric(x)
    + }
    > cnv_unts(Height)
    [1] 165.00 185.00 154.94 154.94 188.00
    

    Data:

    Height <- c("165", "185", "5'1", "5'1", "1.88")