Home > Software engineering >  Why does `mutate(across(...))` with `scale()` adds [,1] to the column header?
Why does `mutate(across(...))` with `scale()` adds [,1] to the column header?

Time:12-16

This seems too basic to not be found in a search, but maybe I didn't use the correct search terms on Google.

I want to normalize a numeric column. When I modify that column with mutate(across(.., scale)) I get [,1] added to the header. Why is that?

library(dplyr, warn.conflicts = FALSE)

mtcars_mpg_only <-
  mtcars %>%
  as_tibble() %>%
  select(mpg)

mtcars_mpg_only %>%
  as_tibble() %>%
  mutate(across(mpg, scale))
#> # A tibble: 32 x 1
#>    mpg[,1]
#>      <dbl>
#>  1   0.151
#>  2   0.151
#>  3   0.450
#>  4   0.217
#>  5  -0.231
#>  6  -0.330
#>  7  -0.961
#>  8   0.715
#>  9   0.450
#> 10  -0.148
#> # ... with 22 more rows

But if I use a different function rather than scale() (e.g., log()), then the column header remains as-is:

mtcars_mpg_only %>%
  as_tibble() %>%
  mutate(across(mpg, log))
#> # A tibble: 32 x 1
#>      mpg
#>    <dbl>
#>  1  3.04
#>  2  3.04
#>  3  3.13
#>  4  3.06
#>  5  2.93
#>  6  2.90
#>  7  2.66
#>  8  3.19
#>  9  3.13
#> 10  2.95
#> # ... with 22 more rows

I know how to remove/rename [,1] after the fact, but my question is why it's created to begin with?

CodePudding user response:

It is because scale returns a matrix whereas log returns a plain vector. The mpg[, 1] is actually a matrix within a data.frame. See ?scale for the definition of its value.

class(scale(mtcars$mpg))
## [1] "matrix" "array" 

class(log(mtcars$mpg))
## [1] "numeric"

Convert the matrix to a plain vector to avoid this, e.g.

mtcars_mpg_only %>%
  mutate(across(mpg, ~ c(scale(.))))

# or extracting first column
mtcars_mpg_only %>%
  mutate(across(mpg, ~ scale(.)[, 1]))

# or normalizing using mean and sd
mtcars_mpg_only %>%
  mutate(across(mpg, ~ (. - mean(.)) / sd(.)))

# or without across
mtcars_mpg_only %>%
  mutate(mpg = c(scale(mpg)))

# or using base R
mtcars_mpg_only |>
  transform(mpg = c(scale(mpg)))
  • Related