Answers:
这是一个可能的plyr解决方案。请注意,它依赖于基本transform()
功能。
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))
(我们可以使用来检查它是否按预期工作with(subset(my.df, sex=="F" & group=="A"), scale(x))
)
基本上,第二个参数描述如何“拆分”数据,第三个参数描述对每个块应用什么功能。上面将x.std
在data.frame后面附加一个变量。使用x
,如果你想通过缩放来替换原来的变量。
这是一个data.table解决方案。它绝对比plyr快(仅与大数据集有关)。也许以后我会做一个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"]
(是的,我重新发现了几年前当我是R新手时问的一个问题;)
这个答案来自Mahmood Arai的白皮书。用居中前缀“ 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))}