Pet*_*etr 8 r dplyr tidyr tidyverse
我想标准化 R 中的变量。我知道如何做到这一点的多种方法。然而,我真的很喜欢使用下面这种方法:
library(tidyverse)
df <- mtcars
df %>%
gather() %>%
group_by(key) %>%
mutate(value = value - mean(value)) %>%
ungroup() %>%
pivot_wider(names_from = key, values_from = value)
Run Code Online (Sandbox Code Playgroud)
由于某种原因,这种方法不起作用,因为我无法将数据返回到原始格式。所以想请教一下
根据当前文档,您应该使用across基于 - 的语法对所需的列子集执行操作。您可以使用everything选择所有列或使用任何其他可用的限定符。group_by仅当您希望对组执行操作时才应使用动词。group_by不是选择变量的正确选择。
mtcars %>%\n as_tibble() %>%\n mutate(across(where(is.numeric), ~ . - mean(.)))\nRun Code Online (Sandbox Code Playgroud)\n至于实际标准化或您想要应用于列子集的任何其他操作,您可以使用:
\n\n\n.fns 应用于每个选定列的函数。可能的\n值为:
\n\n
\n- \n
NULL,返回未转换的列。- 一个函数,例如
\nmean.- purrr 风格的 lambda,例如
\n~ mean(.x, na.rm = TRUE)- 函数/lambda 列表,例如
\nlist(mean = mean, n_miss = ~ sum(is.na(.x))
所以scale你可以这样做:
mtcars %>%\n as_tibble() %>%\n mutate(across(where(is.numeric), scale))\nRun Code Online (Sandbox Code Playgroud)\n或带有附加参数
\nmtcars %>%\n as_tibble() %>%\n mutate(across(where(is.numeric), scale, center = FALSE))\nRun Code Online (Sandbox Code Playgroud)\n正如您从文档中看到的?scale,该函数返回矩阵。在上面的示例中,您将得到只有一列的矩阵,如果这让您感到困扰,您可以这样做:
mtcars %>%\n as_tibble() %>%\n mutate(across(where(is.numeric), ~ scale(.)[,1]))\nRun Code Online (Sandbox Code Playgroud)\n>> mtcars %>%\n... as_tibble() %>%\n... mutate(across(where(is.numeric), ~ scale(.)[,1])) %>% \n... glimpse()\nRows: 32\nColumns: 11\n$ mpg <dbl> 0.15088482, 0.15088482, 0.44954345, 0.21725341, -0.23073453, -0.33028740, -0.96078\xe2\x80\xa6\n$ cyl <dbl> -0.1049878, -0.1049878, -1.2248578, -0.1049878, 1.0148821, -0.1049878, 1.0148821, \xe2\x80\xa6\n$ disp <dbl> -0.57061982, -0.57061982, -0.99018209, 0.22009369, 1.04308123, -0.04616698, 1.0430\xe2\x80\xa6\n$ hp <dbl> -0.53509284, -0.53509284, -0.78304046, -0.53509284, 0.41294217, \n...\n>> \n>> \n>> mtcars %>%\n... as_tibble() %>%\n... mutate(across(where(is.numeric), scale)) %>% \n... glimpse()\nRows: 32\nColumns: 11\n$ mpg <dbl[,1]> <matrix[32 x 1]>\n$ cyl <dbl[,1]> <matrix[32 x 1]>\n$ disp <dbl[,1]> <matrix[32 x 1]>\n$ hp <dbl[,1]> <matrix[32 x 1]>\n...\nRun Code Online (Sandbox Code Playgroud)\n
目前尚不清楚为什么您首先以长格式制作数据然后返回宽格式,也不清楚为什么您不喜欢scale(df)计算速度更快的格式。
无论如何,如果您确实想使用与您喜欢的代码类似的代码,则需要执行进一步的unnest操作才能将数据返回到原始格式。
df %>%
gather() %>%
group_by(key) %>%
mutate(value = value - mean(value)) %>%
ungroup() %>%
pivot_wider(names_from = key, values_from = value) %>%
unnest(everything())
# A tibble: 32 x 11
# mpg cyl disp hp drat wt qsec vs am gear carb
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 0.909 -0.188 -70.7 -36.7 0.303 -0.597 -1.39 -0.438 0.594 0.312 1.19
# 2 0.909 -0.188 -70.7 -36.7 0.303 -0.342 -0.829 -0.438 0.594 0.312 1.19
# 3 2.71 -2.19 -123. -53.7 0.253 -0.897 0.761 0.562 0.594 0.312 -1.81
# 4 1.31 -0.188 27.3 -36.7 -0.517 -0.00225 1.59 0.562 -0.406 -0.688 -1.81
# 5 -1.39 1.81 129. 28.3 -0.447 0.223 -0.829 -0.438 -0.406 -0.688 -0.812
# 6 -1.99 -0.188 -5.72 -41.7 -0.837 0.243 2.37 0.562 -0.406 -0.688 -1.81
# 7 -5.79 1.81 129. 98.3 -0.387 0.353 -2.01 -0.438 -0.406 -0.688 1.19
# 8 4.31 -2.19 -84.0 -84.7 0.0934 -0.0272 2.15 0.562 -0.406 0.312 -0.812
# 9 2.71 -2.19 -89.9 -51.7 0.323 -0.0673 5.05 0.562 -0.406 0.312 -0.812
# 10 -0.891 -0.188 -63.1 -23.7 0.323 0.223 0.451 0.562 -0.406 0.312 1.19
# ... with 22 more rows
Run Code Online (Sandbox Code Playgroud)
为了使用最新的tidyr函数,您应该考虑用以下代码替换gather现已停用的。pivot_longer得到的结果是一样的。
df %>%
pivot_longer(everything()) %>%
group_by(name) %>%
mutate(value = value - mean(value)) %>%
ungroup() %>%
pivot_wider(names_from = name, values_from = value) %>%
unnest(everything())
Run Code Online (Sandbox Code Playgroud)