回答:
データがデータフレームにあり、すべての列が数値である場合scale
、データに対して関数を呼び出すだけで、必要なことを実行できます。
dat <- data.frame(x = rnorm(10, 30, .2), y = runif(10, 3, 5))
scaled.dat <- scale(dat)
# check that we get mean of 0 and sd of 1
colMeans(scaled.dat) # faster version of apply(scaled.dat, 2, mean)
apply(scaled.dat, 2, sd)
組み込み関数の使用は上品です。この猫のように:
質問が古く、1つの回答が受け入れられたことを認識し、参照用に別の回答を提供します。
scale
すべての変数をスケーリングするという事実によって制限されます。以下のソリューションでは、他の変数を変更せずに維持しながら、特定の変数名のみをスケーリングできます(変数名は動的に生成できます)。
library(dplyr)
set.seed(1234)
dat <- data.frame(x = rnorm(10, 30, .2),
y = runif(10, 3, 5),
z = runif(10, 10, 20))
dat
dat2 <- dat %>% mutate_at(c("y", "z"), ~(scale(.) %>% as.vector))
dat2
これは私にこれを与えます:
> dat
x y z
1 29.75859 3.633225 14.56091
2 30.05549 3.605387 12.65187
3 30.21689 3.318092 13.04672
4 29.53086 3.079992 15.07307
5 30.08582 3.437599 11.81096
6 30.10121 4.621197 17.59671
7 29.88505 4.051395 12.01248
8 29.89067 4.829316 12.58810
9 29.88711 4.662690 19.92150
10 29.82199 3.091541 18.07352
そして
> dat2 <- dat %>% mutate_at(c("y", "z"), ~(scale(.) %>% as.vector))
> dat2
x y z
1 29.75859 -0.3004815 -0.06016029
2 30.05549 -0.3423437 -0.72529604
3 30.21689 -0.7743696 -0.58772361
4 29.53086 -1.1324181 0.11828039
5 30.08582 -0.5946582 -1.01827752
6 30.10121 1.1852038 0.99754666
7 29.88505 0.3283513 -0.94806607
8 29.89067 1.4981677 -0.74751378
9 29.88711 1.2475998 1.80753470
10 29.82199 -1.1150515 1.16367556
EDIT 1(2016):ジュリアンのコメントに対処しました:の出力scale
はNx1行列なので、理想的にはを追加しas.vector
て、行列の型をベクトルの型に戻す必要があります。ジュリアン、ありがとう!
EDIT 2(2019):Duccio A.のコメントの引用:最新のdplyr(バージョン0.8)の場合、次のようにdplyr :: funcsをリストで変更する必要がありますdat %>% mutate_each_(list(~scale(.) %>% as.vector), vars=c("y","z"))
編集3(2020):@mj_whalesのおかげで:古いソリューションは非推奨になり、今はを使用する必要がありますmutate_at
。
f(g(x))
よりも、書いた方が見栄えがよくなりますx %>% g %>% f
。つまり、dat %>% mutate_each_(funs(scale),vars=c("y","z"))
ですmutate_each_(dat,funs(scale),vars=c("y","z"))
。オペレーターは、チェーンが非常に長い場合、f(g(h(i(j(x)))))
非常に読みにくくなる可能性があるため、多くのことを助けます。
dplyr
(バージョン0.8)あなたは変更する必要があるdplyr::funcs
とlist
、のようなdat %>% mutate_each_(list(~scale(.) %>% as.vector), vars=c("y","z"))
mutate_each_()
は非推奨になりました。mutate_at()
代わりに使用できます。それを行うための新しい方法は、次のようになりますdat2 <- dat %>% mutate_at(c("y", "z"), scale)
これは3歳です。それでも、以下を追加する必要があると感じています。
最も一般的な正規化はz変換です。この場合、平均を差し引き、変数の標準偏差で割ります。結果は、mean = 0およびsd = 1になります。
そのため、パッケージは必要ありません。
zVar <- (myVar - mean(myVar)) / sd(myVar)
それでおしまい。
mutate(var = (var - mean(var))/sd(var))
。
myVar <- (zVar * sd(zVar)) + mean(zVar)
ますよね?
newVar <- (zVar * sd(myVar)) + mean(myVar)
。元の平均値/標準偏差を使用する必要があります。あなたが書いたように、あなたは掛け算しsd(zVar)=1
て足しますmean(zVar)=0
ので、何も変わりません:)
'Caret'パッケージは、データを前処理するためのメソッドを提供します(例:センタリングとスケーリング)。次のコードを使用することもできます。
library(caret)
# Assuming goal class is column 10
preObj <- preProcess(data[, -10], method=c("center", "scale"))
newData <- predict(preObj, data[, -10])
Dasonによって述べられたソリューションを使用したとき、結果としてデータフレームを取得する代わりに、数値のベクトル(私のdfのスケーリングされた値)を取得しました。
誰かが同じ問題を抱えている場合は、次のようにコードにas.data.frame()を追加する必要があります。
df.scaled <- as.data.frame(scale(df))
これが同じ問題を抱えるPPLに役立つことを願っています!
train_dt[-24] <- scale(train_dt[-24])
。「24」は除外する列番号です
clusterSimパッケージのdata.Normalization関数を使用しても、データを簡単に正規化できます。データの正規化のさまざまな方法を提供します。
data.Normalization (x,type="n0",normalization="column")
議論
x
ベクトル、行列、またはデータセット
タイプの正規化のタイプ:n0-正規化なし
n1-標準化((x-mean)/ sd)
n2-位置の標準化((x-median)/ mad)
n3-単位化((x-mean)/範囲)
n3a-位置の単位化((x-median)/ range)
n4-最小値がゼロの単位化((x-min)/範囲)
n5-範囲<-1,1>の正規化((x-mean)/ max(abs(x-mean)))
n5a-範囲<-1,1>の位置正規化((x-median)/ max(abs(x-median)))
n6-商変換(x / sd)
n6a-位置商変換(x / mad)
n7-商変換(x /範囲)
n8-商変換(x / max)
n9-商変換(x / mean)
n9a-位置商変換(x /中央値)
n10-商変換(x /合計)
n11-商変換(x / sqrt(SSQ))
n12-正規化((x-mean)/ sqrt(sum((x-mean)^ 2)))
n12a-位置正規化((x-median)/ sqrt(sum((x-median)^ 2)))
n13-ゼロを中心点とする正規化((x-midrange)/(range / 2))
正規化
「列」-変数による正規化、「行」-オブジェクトによる正規化
dplyr
v0.7.4 では、次のコマンドを使用してすべての変数をスケーリングできますmutate_all()
。
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(tibble)
set.seed(1234)
dat <- tibble(x = rnorm(10, 30, .2),
y = runif(10, 3, 5),
z = runif(10, 10, 20))
dat %>% mutate_all(scale)
#> # A tibble: 10 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 -0.827 -0.300 -0.0602
#> 2 0.663 -0.342 -0.725
#> 3 1.47 -0.774 -0.588
#> 4 -1.97 -1.13 0.118
#> 5 0.816 -0.595 -1.02
#> 6 0.893 1.19 0.998
#> 7 -0.192 0.328 -0.948
#> 8 -0.164 1.50 -0.748
#> 9 -0.182 1.25 1.81
#> 10 -0.509 -1.12 1.16
特定の変数は、以下を使用して除外できますmutate_at()
。
dat %>% mutate_at(scale, .vars = vars(-x))
#> # A tibble: 10 x 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 29.8 -0.300 -0.0602
#> 2 30.1 -0.342 -0.725
#> 3 30.2 -0.774 -0.588
#> 4 29.5 -1.13 0.118
#> 5 30.1 -0.595 -1.02
#> 6 30.1 1.19 0.998
#> 7 29.9 0.328 -0.948
#> 8 29.9 1.50 -0.748
#> 9 29.9 1.25 1.81
#> 10 29.8 -1.12 1.16
reprexパッケージ(v0.2.0)によって2018-04-24に作成されました。
繰り返しになりますが、これは古い質問ですが、非常に関連があります。そして、パッケージを必要とせずに特定の列を正規化する簡単な方法を見つけました:
normFunc <- function(x){(x-mean(x, na.rm = T))/sd(x, na.rm = T)}
例えば
x<-rnorm(10,14,2)
y<-rnorm(10,7,3)
z<-rnorm(10,18,5)
df<-data.frame(x,y,z)
df[2:3] <- apply(df[2:3], 2, normFunc)
y列とz列が正規化されていることがわかります。パッケージは必要ありません:-)
dplyr
パッケージには、これを行う2つの機能があります。
> require(dplyr)
突然変異する特定のデータテーブルの列は、関数を使用することができますmutate_at()
。突然変異するすべての列を、あなたが使用することができますmutate_all
。
以下は、これらの関数を使用してデータを標準化する簡単な例です。
特定の列を変更する:
dt = data.table(a = runif(3500), b = runif(3500), c = runif(3500))
dt = data.table(dt %>% mutate_at(vars("a", "c"), scale)) # can also index columns by number, e.g., vars(c(1,3))
> apply(dt, 2, mean)
a b c
1.783137e-16 5.064855e-01 -5.245395e-17
> apply(dt, 2, sd)
a b c
1.0000000 0.2906622 1.0000000
すべての列を変更:
dt = data.table(a = runif(3500), b = runif(3500), c = runif(3500))
dt = data.table(dt %>% mutate_all(scale))
> apply(dt, 2, mean)
a b c
-1.728266e-16 9.291994e-17 1.683551e-16
> apply(dt, 2, sd)
a b c
1 1 1
偶然このスレッドを見つける前に、私は同じ問題を抱えていました。ユーザー依存の列タイプがあったのでfor
、それらをループして必要な列を取得するループを書きましたscale
。おそらくもっと良い方法がありますが、これは問題をうまく解決しました:
for(i in 1:length(colnames(df))) {
if(class(df[,i]) == "numeric" || class(df[,i]) == "integer") {
df[,i] <- as.vector(scale(df[,i])) }
}
as.vector
それが判明したので、必要な部分ですscale
しrownames x 1
、あなたの中に持っていたいものは通常ではない行列をdata.frame
。
パッケージ「recommenderlab」を使用してください。パッケージをダウンロードしてインストールします。このパッケージには、「正規化」コマンドが組み込まれています。また、正規化のための多くの方法の1つ、つまり「中央」または「Zスコア」を選択することもできます。次の例に従ってください。
## create a matrix with ratings
m <- matrix(sample(c(NA,0:5),50, replace=TRUE, prob=c(.5,rep(.5/6,6))),nrow=5, ncol=10, dimnames = list(users=paste('u', 1:5, sep=”), items=paste('i', 1:10, sep=”)))
## do normalization
r <- as(m, "realRatingMatrix")
#here, 'centre' is the default method
r_n1 <- normalize(r)
#here "Z-score" is the used method used
r_n2 <- normalize(r, method="Z-score")
r
r_n1
r_n2
## show normalized data
image(r, main="Raw Data")
image(r_n1, main="Centered")
image(r_n2, main="Z-Score Normalization")
BBMiscパッケージの正規化関数は、NA値を処理できるため、私にとって適切なツールでした。
使用方法は次のとおりです。
次のデータセットを考えると、
ASR_API <- c("CV", "F", "IER", "LS-c", "LS-o")
Human <- c(NA, 5.8, 12.7, NA, NA)
Google <- c(23.2, 24.2, 16.6, 12.1, 28.8)
GoogleCloud <- c(23.3, 26.3, 18.3, 12.3, 27.3)
IBM <- c(21.8, 47.6, 24.0, 9.8, 25.3)
Microsoft <- c(29.1, 28.1, 23.1, 18.8, 35.9)
Speechmatics <- c(19.1, 38.4, 21.4, 7.3, 19.4)
Wit_ai <- c(35.6, 54.2, 37.4, 19.2, 41.7)
dt <- data.table(ASR_API,Human, Google, GoogleCloud, IBM, Microsoft, Speechmatics, Wit_ai)
> dt
ASR_API Human Google GoogleCloud IBM Microsoft Speechmatics Wit_ai
1: CV NA 23.2 23.3 21.8 29.1 19.1 35.6
2: F 5.8 24.2 26.3 47.6 28.1 38.4 54.2
3: IER 12.7 16.6 18.3 24.0 23.1 21.4 37.4
4: LS-c NA 12.1 12.3 9.8 18.8 7.3 19.2
5: LS-o NA 28.8 27.3 25.3 35.9 19.4 41.7
正規化された値は次のようにして取得できます。
> dtn <- normalize(dt, method = "standardize", range = c(0, 1), margin = 1L, on.constant = "quiet")
> dtn
ASR_API Human Google GoogleCloud IBM Microsoft Speechmatics Wit_ai
1: CV NA 0.3361245 0.2893457 -0.28468670 0.3247336 -0.18127203 -0.16032655
2: F -0.7071068 0.4875320 0.7715885 1.59862532 0.1700986 1.55068347 1.31594762
3: IER 0.7071068 -0.6631646 -0.5143923 -0.12409420 -0.6030768 0.02512682 -0.01746131
4: LS-c NA -1.3444981 -1.4788780 -1.16064578 -1.2680075 -1.24018782 -1.46198764
5: LS-o NA 1.1840062 0.9323361 -0.02919864 1.3762521 -0.15435044 0.32382788
ここで、手動で計算されたメソッドはNAを含む列を無視します。
> dt %>% mutate(normalizedHuman = (Human - mean(Human))/sd(Human)) %>%
+ mutate(normalizedGoogle = (Google - mean(Google))/sd(Google)) %>%
+ mutate(normalizedGoogleCloud = (GoogleCloud - mean(GoogleCloud))/sd(GoogleCloud)) %>%
+ mutate(normalizedIBM = (IBM - mean(IBM))/sd(IBM)) %>%
+ mutate(normalizedMicrosoft = (Microsoft - mean(Microsoft))/sd(Microsoft)) %>%
+ mutate(normalizedSpeechmatics = (Speechmatics - mean(Speechmatics))/sd(Speechmatics)) %>%
+ mutate(normalizedWit_ai = (Wit_ai - mean(Wit_ai))/sd(Wit_ai))
ASR_API Human Google GoogleCloud IBM Microsoft Speechmatics Wit_ai normalizedHuman normalizedGoogle
1 CV NA 23.2 23.3 21.8 29.1 19.1 35.6 NA 0.3361245
2 F 5.8 24.2 26.3 47.6 28.1 38.4 54.2 NA 0.4875320
3 IER 12.7 16.6 18.3 24.0 23.1 21.4 37.4 NA -0.6631646
4 LS-c NA 12.1 12.3 9.8 18.8 7.3 19.2 NA -1.3444981
5 LS-o NA 28.8 27.3 25.3 35.9 19.4 41.7 NA 1.1840062
normalizedGoogleCloud normalizedIBM normalizedMicrosoft normalizedSpeechmatics normalizedWit_ai
1 0.2893457 -0.28468670 0.3247336 -0.18127203 -0.16032655
2 0.7715885 1.59862532 0.1700986 1.55068347 1.31594762
3 -0.5143923 -0.12409420 -0.6030768 0.02512682 -0.01746131
4 -1.4788780 -1.16064578 -1.2680075 -1.24018782 -1.46198764
5 0.9323361 -0.02919864 1.3762521 -0.15435044 0.32382788
(normalizedHumanはNAのリストになります...)
計算用の特定の列の選択に関しては、次のような一般的な方法を使用できます。
data_vars <- df_full %>% dplyr::select(-ASR_API,-otherVarNotToBeUsed)
meta_vars <- df_full %>% dplyr::select(ASR_API,otherVarNotToBeUsed)
data_varsn <- normalize(data_vars, method = "standardize", range = c(0, 1), margin = 1L, on.constant = "quiet")
dtn <- cbind(meta_vars,data_varsn)