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.
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.
Odpowiedzi:
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.std
do data.frame. Użyj, x
jeśli chcesz zastąpić oryginalną zmienną skalowaną.
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;)
Możesz do tego użyć (między innymi) tapply
( plyr
pakiet zawiera wiele innych opcji, które mogą być lepiej dostosowane do konkretnej sytuacji):
tapply(variabletoscale, list(groupvar1, groupvar2), scale)
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))}
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)))