创建标准化多个变量并创建新列的 r 函数
Create r function that standardizes multiple variables and creates new columns
我有一个数据集,其中我使用许多变量的均值中心和标准化版本。在我的 r 代码中,我有一个很大的 scale() 函数列表,我 运行 用于所有变量,但我想知道是否有一种方法可以编写一个简单的函数来优化这个过程。
例如:与其拥有像这样的庞大列表...
df$Z.ROW1 <- scale(df$ROW1, scale=T)
df$Z.ROW2 <- scale(df$ROW2, scale=T)
df$Z.ROW3 <- scale(df$ROW3, scale=T)
.....
有没有办法编写一个函数来创建新的向量,并根据我指定要标准化的变量将它们附加到数据框的末尾?
我在网上找到了这个 example:
set.seed(212)
df = matrix(rnorm(15), 5, 5))
colnames(df) <- c("ROW1", "ROW2", "ROW3", "ROW4", "ROW5")
df
ROW1 ROW2 ROW3 ROW4 ROW5
[1,] -0.2391731 0.1544909 0.1503488 -0.2391731 0.1544909
[2,] 0.6769356 1.0368712 0.5096765 0.6769356 1.0368712
[3,] -2.4403360 -0.7796077 -0.7733148 -2.4403360 -0.7796077
[4,] 1.2408845 0.6212641 1.8756660 1.2408845 0.6212641
[5,] -0.3265144 0.2994313 0.7883057 -0.3265144 0.2994313
center.scale <- function(z) {
scale(z, scale = T)
}
center.scale(df[,c("ROW1", "ROW2")])
ROW1 ROW2
[1,] -0.01534097 -0.1657064
[2,] 0.63734894 1.1398052
[3,] -1.58357932 -1.5477370
[4,] 1.03913941 0.5249004
[5,] -0.07756806 0.0487378
这很接近,但它没有解决创建新向量并将它们附加到我现有数据集末尾的问题。理想情况下,我希望这样我唯一需要更改的是 center.scale() 函数中的变量名称。谢谢!
如果我对你的问题的理解正确,你可以cbind
将scale
的输出转化为原始数据,正如@Dason所建议的那样。
示例:
> df <- data.frame(ROW1 = c(1,2,1,1), ROW2 = c(1,2,3,4), ROW3 = c(5,8,6,5))
> df
ROW1 ROW2 ROW3
1 1 1 5
2 2 2 8
3 1 3 6
4 1 4 5
> df <- cbind(df, scale(df, scale = T))
> names(df)[4:6] <- paste0('Z.', names(df)[4:6])
> df
ROW1 ROW2 ROW3 Z.ROW1 Z.ROW2 Z.ROW3
1 1 1 5 -0.5 -1.1618950 -0.7071068
2 2 2 8 1.5 -0.3872983 1.4142136
3 1 3 6 -0.5 0.3872983 0.0000000
4 1 4 5 -0.5 1.1618950 -0.7071068
如@Dason 所说,您只需将原始数据中的函数修改为 cbind
,并相应地命名新列。
center.scale <- function(z) {
x <- scale(z, scale = T)
colnames(x) <- paste0("scale_", colnames(x))
cbind(z, x)
}
center.scale(df[,c("ROW1", "ROW2")])
结果:
ROW1 ROW2 scale_ROW1 scale_ROW2
[1,] -0.2391731 0.1544909 -0.01534097 -0.1657064
[2,] 0.6769356 1.0368712 0.63734894 1.1398052
[3,] -2.4403360 -0.7796077 -1.58357932 -1.5477370
[4,] 1.2408845 0.6212641 1.03913941 0.5249004
[5,] -0.3265144 0.2994313 -0.07756806 0.0487378
这是一个不对 scale
选项进行硬编码的版本,并允许您 select 原始列的子集。它 returns a data.frame
因为它在更多情况下会有用,但如果您愿意,您可以轻松地将其修改为 return a matrix
。
add_scaled <- function(data, vars = colnames(data), ...) {
data.frame(data,
setNames(data.frame(scale(data[, vars, drop = FALSE],
...)),
paste("Z", vars, sep = ".")))
}
默认情况下,它 return 是一个 data.frame
,所有列都已标准化并附加。
df = matrix(rnorm(15), 5, 3)
colnames(df) <- paste0("Col", 1:ncol(df))
df
## Col1 Col2 Col3
## [1,] 1.9659082 -1.2254071 0.1477912
## [2,] 0.2666273 -0.9123931 1.4747579
## [3,] 1.0813351 2.4138457 -1.5569830
## [4,] 0.9618084 1.3076966 -0.8646893
## [5,] -2.0246095 0.3043559 -1.3617747
add_scaled(df)
## Col1 Col2 Col3 Z.Col1 Z.Col2 Z.Col3
## 1 1.9659082 -1.2254071 0.1477912 1.0040228 -1.05411792 0.4625295
## 2 0.2666273 -0.9123931 1.4747579 -0.1216110 -0.84828629 1.5207917
## 3 1.0813351 2.4138457 -1.5569830 0.4180659 1.33898111 -0.8970361
## 4 0.9618084 1.3076966 -0.8646893 0.3388893 0.61159985 -0.3449285
## 5 -2.0246095 0.3043559 -1.3617747 -1.6393669 -0.04817676 -0.7413566
如果只有一些列应该标准化,您可以 select 它们。
add_scaled(df, vars = c("Col1", "Col3"))
## Col1 Col2 Col3 Z.Col1 Z.Col3
## 1 1.9659082 -1.2254071 0.1477912 1.0040228 0.4625295
## 2 0.2666273 -0.9123931 1.4747579 -0.1216110 1.5207917
## 3 1.0813351 2.4138457 -1.5569830 0.4180659 -0.8970361
## 4 0.9618084 1.3076966 -0.8646893 0.3388893 -0.3449285
## 5 -2.0246095 0.3043559 -1.3617747 -1.6393669 -0.7413566
最后,您可以将参数传递给 scale
,这样您就不会失去任何灵活性。
add_scaled(df, vars = "Col1", center = FALSE, scale = TRUE)
## Col1 Col2 Col3 Z.Col1
## 1 1.9659082 -1.2254071 0.1477912 1.2353890
## 2 0.2666273 -0.9123931 1.4747579 0.1675502
## 3 1.0813351 2.4138457 -1.5569830 0.6795177
## 4 0.9618084 1.3076966 -0.8646893 0.6044064
## 5 -2.0246095 0.3043559 -1.3617747 -1.2722773
add_scaled(df, vars = "Col1", center = TRUE, scale = FALSE)
## Col1 Col2 Col3 Z.Col1
## 1 1.9659082 -1.2254071 0.1477912 1.5156943
## 2 0.2666273 -0.9123931 1.4747579 -0.1835866
## 3 1.0813351 2.4138457 -1.5569830 0.6311212
## 4 0.9618084 1.3076966 -0.8646893 0.5115945
## 5 -2.0246095 0.3043559 -1.3617747 -2.4748234
我有一个数据集,其中我使用许多变量的均值中心和标准化版本。在我的 r 代码中,我有一个很大的 scale() 函数列表,我 运行 用于所有变量,但我想知道是否有一种方法可以编写一个简单的函数来优化这个过程。
例如:与其拥有像这样的庞大列表...
df$Z.ROW1 <- scale(df$ROW1, scale=T)
df$Z.ROW2 <- scale(df$ROW2, scale=T)
df$Z.ROW3 <- scale(df$ROW3, scale=T)
.....
有没有办法编写一个函数来创建新的向量,并根据我指定要标准化的变量将它们附加到数据框的末尾?
我在网上找到了这个 example:
set.seed(212)
df = matrix(rnorm(15), 5, 5))
colnames(df) <- c("ROW1", "ROW2", "ROW3", "ROW4", "ROW5")
df
ROW1 ROW2 ROW3 ROW4 ROW5
[1,] -0.2391731 0.1544909 0.1503488 -0.2391731 0.1544909
[2,] 0.6769356 1.0368712 0.5096765 0.6769356 1.0368712
[3,] -2.4403360 -0.7796077 -0.7733148 -2.4403360 -0.7796077
[4,] 1.2408845 0.6212641 1.8756660 1.2408845 0.6212641
[5,] -0.3265144 0.2994313 0.7883057 -0.3265144 0.2994313
center.scale <- function(z) {
scale(z, scale = T)
}
center.scale(df[,c("ROW1", "ROW2")])
ROW1 ROW2
[1,] -0.01534097 -0.1657064
[2,] 0.63734894 1.1398052
[3,] -1.58357932 -1.5477370
[4,] 1.03913941 0.5249004
[5,] -0.07756806 0.0487378
这很接近,但它没有解决创建新向量并将它们附加到我现有数据集末尾的问题。理想情况下,我希望这样我唯一需要更改的是 center.scale() 函数中的变量名称。谢谢!
如果我对你的问题的理解正确,你可以cbind
将scale
的输出转化为原始数据,正如@Dason所建议的那样。
示例:
> df <- data.frame(ROW1 = c(1,2,1,1), ROW2 = c(1,2,3,4), ROW3 = c(5,8,6,5))
> df
ROW1 ROW2 ROW3
1 1 1 5
2 2 2 8
3 1 3 6
4 1 4 5
> df <- cbind(df, scale(df, scale = T))
> names(df)[4:6] <- paste0('Z.', names(df)[4:6])
> df
ROW1 ROW2 ROW3 Z.ROW1 Z.ROW2 Z.ROW3
1 1 1 5 -0.5 -1.1618950 -0.7071068
2 2 2 8 1.5 -0.3872983 1.4142136
3 1 3 6 -0.5 0.3872983 0.0000000
4 1 4 5 -0.5 1.1618950 -0.7071068
如@Dason 所说,您只需将原始数据中的函数修改为 cbind
,并相应地命名新列。
center.scale <- function(z) {
x <- scale(z, scale = T)
colnames(x) <- paste0("scale_", colnames(x))
cbind(z, x)
}
center.scale(df[,c("ROW1", "ROW2")])
结果:
ROW1 ROW2 scale_ROW1 scale_ROW2
[1,] -0.2391731 0.1544909 -0.01534097 -0.1657064
[2,] 0.6769356 1.0368712 0.63734894 1.1398052
[3,] -2.4403360 -0.7796077 -1.58357932 -1.5477370
[4,] 1.2408845 0.6212641 1.03913941 0.5249004
[5,] -0.3265144 0.2994313 -0.07756806 0.0487378
这是一个不对 scale
选项进行硬编码的版本,并允许您 select 原始列的子集。它 returns a data.frame
因为它在更多情况下会有用,但如果您愿意,您可以轻松地将其修改为 return a matrix
。
add_scaled <- function(data, vars = colnames(data), ...) {
data.frame(data,
setNames(data.frame(scale(data[, vars, drop = FALSE],
...)),
paste("Z", vars, sep = ".")))
}
默认情况下,它 return 是一个 data.frame
,所有列都已标准化并附加。
df = matrix(rnorm(15), 5, 3)
colnames(df) <- paste0("Col", 1:ncol(df))
df
## Col1 Col2 Col3
## [1,] 1.9659082 -1.2254071 0.1477912
## [2,] 0.2666273 -0.9123931 1.4747579
## [3,] 1.0813351 2.4138457 -1.5569830
## [4,] 0.9618084 1.3076966 -0.8646893
## [5,] -2.0246095 0.3043559 -1.3617747
add_scaled(df)
## Col1 Col2 Col3 Z.Col1 Z.Col2 Z.Col3
## 1 1.9659082 -1.2254071 0.1477912 1.0040228 -1.05411792 0.4625295
## 2 0.2666273 -0.9123931 1.4747579 -0.1216110 -0.84828629 1.5207917
## 3 1.0813351 2.4138457 -1.5569830 0.4180659 1.33898111 -0.8970361
## 4 0.9618084 1.3076966 -0.8646893 0.3388893 0.61159985 -0.3449285
## 5 -2.0246095 0.3043559 -1.3617747 -1.6393669 -0.04817676 -0.7413566
如果只有一些列应该标准化,您可以 select 它们。
add_scaled(df, vars = c("Col1", "Col3"))
## Col1 Col2 Col3 Z.Col1 Z.Col3
## 1 1.9659082 -1.2254071 0.1477912 1.0040228 0.4625295
## 2 0.2666273 -0.9123931 1.4747579 -0.1216110 1.5207917
## 3 1.0813351 2.4138457 -1.5569830 0.4180659 -0.8970361
## 4 0.9618084 1.3076966 -0.8646893 0.3388893 -0.3449285
## 5 -2.0246095 0.3043559 -1.3617747 -1.6393669 -0.7413566
最后,您可以将参数传递给 scale
,这样您就不会失去任何灵活性。
add_scaled(df, vars = "Col1", center = FALSE, scale = TRUE)
## Col1 Col2 Col3 Z.Col1
## 1 1.9659082 -1.2254071 0.1477912 1.2353890
## 2 0.2666273 -0.9123931 1.4747579 0.1675502
## 3 1.0813351 2.4138457 -1.5569830 0.6795177
## 4 0.9618084 1.3076966 -0.8646893 0.6044064
## 5 -2.0246095 0.3043559 -1.3617747 -1.2722773
add_scaled(df, vars = "Col1", center = TRUE, scale = FALSE)
## Col1 Col2 Col3 Z.Col1
## 1 1.9659082 -1.2254071 0.1477912 1.5156943
## 2 0.2666273 -0.9123931 1.4747579 -0.1835866
## 3 1.0813351 2.4138457 -1.5569830 0.6311212
## 4 0.9618084 1.3076966 -0.8646893 0.5115945
## 5 -2.0246095 0.3043559 -1.3617747 -2.4748234