Bagaimana cara group-center / standardisasi variabel dalam R?

9

Fungsi Aku akrab dengan menyertakan skala dari basis R, rescale dari ARM.

Mungkin cara terbaik adalah menggunakan beberapa varian berlaku, menentukan satu atau lebih variabel untuk digunakan sebagai variabel pengelompokan.

Michael Bishop
sumber
Coba: agregat (state.x77, daftar (Wilayah = state.region, Dingin = state.x77 [, "Frost"]> 130)), fungsi (x) ((x - mean (x)) / sd (x) ))
suncoolsu

Jawaban:

7

Berikut adalah solusi plyr yang mungkin . Perhatikan bahwa ini bergantung pada transform()fungsi dasar .

my.df <- data.frame(x=rnorm(100, mean=10), 
                    sex=sample(c("M","F"), 100, rep=T), 
                    group=gl(5, 20, labels=LETTERS[1:5]))
library(plyr)
ddply(my.df, c("sex", "group"), transform, x.std = scale(x))

(Kita dapat memeriksa apakah itu berfungsi seperti yang diharapkan dengan misalnya, with(subset(my.df, sex=="F" & group=="A"), scale(x)))

Pada dasarnya, argumen ke-2 menjelaskan bagaimana cara "membagi" data, argumen ke-3 apa fungsi yang berlaku untuk setiap chunk. Di atas akan menambahkan variabel x.stdke data.frame. Gunakan xjika Anda ingin mengganti variabel asli Anda dengan yang diskalakan.

chl
sumber
7
group.center <- function(var,grp) {
    return(var-tapply(var,grp,mean,na.rm=T)[grp])
}
Thanassi
sumber
3

Berikut ini adalah solusi data.table . Ini jelas lebih cepat dari plyr (hanya relevan untuk set data besar). Mungkin nanti saya akan membuat contoh dplyr.

# generate example data
raw.data <- data.frame( outcome = c(rnorm(500, 100, 15), rnorm(500, 110, 12)), 
                        group = c(rep("a", 500), rep("b", 500)))

library(data.table)
# convert dataframe to data.table
raw.data <- data.table(raw.data, key = "group")

# create group standardized outcome variable
raw.data[ , group_std_outcome := (outcome - mean(outcome, na.rm = TRUE)) /  
           sd(outcome, na.rm = TRUE), "group"]

(Ya, saya menemukan kembali pertanyaan yang saya tanyakan bertahun-tahun yang lalu ketika saya masih kecil;)

Michael Bishop
sumber
2

Anda dapat menggunakan (antara lain) tapplyuntuk ini ( plyrpaket berisi banyak opsi lain yang mungkin lebih cocok untuk situasi spesifik Anda):

tapply(variabletoscale, list(groupvar1, groupvar2), scale)
Nick Sabbe
sumber
1
Dengan dua faktor, itu tidak akan mengembalikan data.frame. Anda harus memposting proses untuk hasilnya.
chl
0

Jawaban ini dari kertas putih oleh Mahmood Arai. Ini memiliki efek samping yang nyaman dengan memberi label hasil yang terpusat dengan awalan "C.":

gcenter <- function(df1,group) {
        variables <- paste(
              rep("C", ncol(df1)),  colnames(df1), sep=".")
        copydf <- df1
        for (i in 1:ncol(df1)) {
              copydf[,i] <- df1[,i] - ave(df1[,i], group, FUN=mean)}
        colnames(copydf) <- variables
        return(cbind(df1,copydf))}
RegressForward
sumber
0

Berikut ini adalah implementasi yang diperbarui menggunakan dplyr dari tidyverse .

library(tidyverse)

my.df <- data.frame(x=rnorm(100, mean=10), sex=sample(c("M","F"), 100, rep=T))
my.df <- group_by(my.df, sex) %>% mutate(x.sd = as.numeric(scale(x)))
Brian Levey
sumber