Las funciones con las que estoy familiarizado incluyen escalar desde la base R, reescalar desde ARM.
Quizás la mejor manera sería usar alguna variante de apply, especificando una o más variables para usar como variables de agrupación.
Las funciones con las que estoy familiarizado incluyen escalar desde la base R, reescalar desde ARM.
Quizás la mejor manera sería usar alguna variante de apply, especificando una o más variables para usar como variables de agrupación.
Respuestas:
Aquí hay una posible solución de capas . Tenga en cuenta que se basa en la transform()
función 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))
(Podemos verificar si funciona como se espera con, por ejemplo, with(subset(my.df, sex=="F" & group=="A"), scale(x))
)
Básicamente, el segundo argumento describe cómo "dividir" los datos, el tercer argumento qué función aplicar a cada fragmento. Lo anterior agregará una variable x.std
al data.frame. Úselo x
si desea reemplazar su variable original por la escala.
Aquí hay una solución data.table . Definitivamente es más rápido que plyr (relevante solo para grandes conjuntos de datos). Quizás más tarde haga un ejemplo de 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í, redescubrí una pregunta que hice hace años cuando era un novato R;)
Puede usar (entre otros) tapply
para esto (el plyr
paquete contiene muchas otras opciones que pueden ser más adecuadas para su situación específica):
tapply(variabletoscale, list(groupvar1, groupvar2), scale)
Esta respuesta es de un libro blanco de Mahmood Arai. Tiene el conveniente efecto secundario de etiquetar los resultados centrados con el prefijo "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))}
Aquí hay una implementación actualizada usando dplyr de 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)))