为什么`mutate(across(...))`和`scale()`会在列标题中添加[,1]?

new9mtju  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(75)

这似乎太基本了,在搜索中找不到,但也许我没有在谷歌上使用正确的搜索词。
我想规范化一个数值列。当我用mutate(across(.., scale))修改该列时,我会将[,1]添加到标题中。为什么会这样?

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

字符串
但是如果我使用不同的函数而不是scale()(例如,log()),那么列标题保持原样:

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


我知道如何删除/重命名[,1]后的事实,但我的问题是为什么它的创建开始?

3pvhb19x

3pvhb19x1#

这是因为scale返回一个矩阵,而log返回一个普通的向量。mpg[,1]实际上是一个data.frame中的矩阵。有关其值的定义,请参阅?scale。

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

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

字符串
将矩阵转换为普通向量以避免这种情况,例如。

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)))

相关问题