Search code examples
rtibble

Mutate is adding $ dollar sign to column name


I have the data below that I'm using to calculate another column using the function below. Using pick with starts_with and ends_with ends with the result having a $ in the column name with the input column name appended (see output below). This causes issues later trying to refer to the new column by name. If I refer to the input column without the string quotes, the column name comes out as expected. Is there a mistake with how my function is calculating the new column?

Input Data Sample

> data
structure(list(tmpc39000 = c(-55, -56, -56, -57, -56, -56), tmpc45000 = c(-64, 
-65, -64, -63, -64, -64), tmpc53000 = c(-64, -64, -63, -63, -64, 
-63)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
))

My Function

knots_to_ms <- 0.51444
gamma <- 1.4
r_star <- 287.053
degc_to_degk <- 273.15

calc_tas <- function(mach, temp, units = "knots") {
  if (units == "knots") {
    speed_mult <- 1 / knots_to_ms
  } else {
    speed_mult <- 1
  }

  speed_sound <- sqrt(gamma * r_star * (temp + degc_to_degk))
  tas <- speed_mult * mach * speed_sound
  tas
}

Function Call

mach <- 2.04
alt <- "53000"

spdata <- data %>%
  mutate(
    tas = calc_tas(mach, pick(starts_with("tmpc") & ends_with(alt)))
  )

Actual Output

> spdata
structure(list(tmpc39000 = c(-55, -56, -56, -57, -56, -56), tmpc45000 = c(-64, 
-65, -64, -63, -64, -64), tmpc53000 = c(-64, -64, -63, -63, -64, 
-63), tas = structure(list(tmpc53000 = c(1149.6502039295, 1149.6502039295, 
1152.39531338665, 1152.39531338665, 1149.6502039295, 1152.39531338665
)), row.names = c(NA, -6L), class = "data.frame")), row.names = c(NA, 
-6L), class = c("tbl_df", "tbl", "data.frame"))

Expected Output Note change in name for the last column

> spdata
structure(list(tmpc39000 = c(-55, -56, -56, -57, -56, -56), tmpc45000 = c(-64, 
-65, -64, -63, -64, -64), tmpc53000 = c(-64, -64, -63, -63, -64, 
-63), tas = c(1174.12516099369, 1171.43097396222, 1171.43097396222, 
1168.73057623976, 1171.43097396222, 1171.43097396222)), row.names = c(NA, 
-6L), class = c("tbl_df", "tbl", "data.frame"))

Solution

  • alt <-  "53000"
    
    data %>%
      mutate(tas = calc_tas(mach, .data[[ paste0("tmpc", alt) ]]))
    

    or, similar to @jdobres's comment:

    data %>%
      mutate(across(starts_with("tmpc") & ends_with(alt), 
             \(x) calc_tas(mach, x), .names = "tas"))
    

    Result

    # A tibble: 6 × 4
      tmpc39000 tmpc45000 tmpc53000   tas
          <dbl>     <dbl>     <dbl> <dbl>
    1       -55       -64       -64 1150.
    2       -56       -65       -64 1150.
    3       -56       -64       -63 1152.
    4       -57       -63       -63 1152.
    5       -56       -64       -64 1150.
    6       -56       -64       -63 1152.
    

    See https://dplyr.tidyverse.org/articles/programming.html#indirection