Jak grupować / standaryzować zmienne w R?


9

Znane mi funkcje obejmują skalowanie od podstawy R, przeskalowanie od ARM.

Być może najlepszym sposobem byłoby użycie jakiegoś wariantu zastosowania, określając jedną lub więcej zmiennych do zastosowania jako zmienne grupujące.


Wypróbuj: agreguj (stan.x77, lista (Region = region.region, Zimno = stan.x77 [, „Frost”]> 130)), funkcja (x) ((x - średnia (x)) / sd (x) ))
suncoolsu,

Odpowiedzi:


7

Oto możliwe plyr rozwiązanie. Zauważ, że opiera się on na transform()funkcji podstawowej .

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

(Możemy sprawdzić, czy działa zgodnie z oczekiwaniami, np. with(subset(my.df, sex=="F" & group=="A"), scale(x)))

Zasadniczo drugi argument opisuje, jak „podzielić” dane, trzeci argument to, jaką funkcję zastosować do każdej porcji. Powyższe spowoduje dołączenie zmiennej x.stddo data.frame. Użyj, xjeśli chcesz zastąpić oryginalną zmienną skalowaną.


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

3

Oto rozwiązanie data.table . Jest zdecydowanie szybszy niż plyr (dotyczy tylko dużych zestawów danych). Może później zrobię lepszy przykład.

# 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"]

(Tak, odkryłem pytanie, które zadałem lata temu, kiedy byłem R noobem;)


2

Możesz do tego użyć (między innymi) tapply( plyrpakiet zawiera wiele innych opcji, które mogą być lepiej dostosowane do konkretnej sytuacji):

tapply(variabletoscale, list(groupvar1, groupvar2), scale)

1
Z dwoma czynnikami nie zwróci ramki danych. W tym celu musisz przetworzyć wynik.
chl

0

Ta odpowiedź pochodzi z białej księgi Mahmood Arai. Ma wygodny efekt uboczny, oznaczając wyśrodkowane wyniki przedrostkiem „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))}

0

Oto zaktualizowana implementacja wykorzystująca dplyr z 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)))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.