Le funzioni che conosco includono la scala dalla base R, il riscalamento da ARM.
Forse il modo migliore sarebbe usare una variante di applicare, specificando una o più variabili da usare come variabili di raggruppamento.
Le funzioni che conosco includono la scala dalla base R, il riscalamento da ARM.
Forse il modo migliore sarebbe usare una variante di applicare, specificando una o più variabili da usare come variabili di raggruppamento.
Risposte:
Ecco una possibile soluzione plyr . Si noti che si basa sulla transform()
funzione di base .
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))
(Possiamo verificare se funziona come previsto, ad es. with(subset(my.df, sex=="F" & group=="A"), scale(x))
)
Fondamentalmente, il secondo argomento descrive come "dividere" i dati, il terzo argomento quale funzione applicare a ciascun blocco. Quanto sopra aggiungerà una variabile x.std
a data.frame. Utilizzare x
se si desidera sostituire la variabile originale con quella in scala.
Ecco una soluzione data.table . È decisamente più veloce di plyr (rilevante solo per grandi set di dati). Forse dopo farò un esempio 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"]
(Sì, ho riscoperto una domanda che ho fatto anni fa quando ero un Noob R;)
Puoi usare (tra gli altri) tapply
per questo (il plyr
pacchetto contiene molte altre opzioni che potrebbero essere più adatte alla tua specifica situazione):
tapply(variabletoscale, list(groupvar1, groupvar2), scale)
Questa risposta è tratta da un white paper di Mahmood Arai. Ha il comodo effetto collaterale di etichettare i risultati centrati con il prefisso "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))}
Ecco un'implementazione aggiornata usando dplyr di 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)))