向量化创建包含对应于分类变量的均值的向量

Vectorize creation of vector containing means corresponding to categorical variable

Data 包含 label 变量和数字 x 变量,然后我计算 label 指定的组中 x 的平均值(means 对象被创建,然后我们将其用作字典),那么我想 创建包含重复与 label 变量对应的平均值的新向量,下面的示例使用 for(),我不知道如何对其进行向量化,似乎唯一的可能性是使用 merge 函数,问题是:

  1. merge 是否提供矢量化的好处(我的原始数据集,有几百万个观察值)?

  2. 如果不是,那么是否可以对 y 的创建进行矢量化?

我当前的代码是:

set.seed(123)

data<-data.frame(label=sample(c("A","B"),10,replace=TRUE),x=rnorm(10))
data
#   label          x
#1      A  1.7150650
#2      B  0.4609162
#3      A -1.2650612
#4      B -0.6868529
#5      B -0.4456620
#6      A  1.2240818
#7      B  0.3598138
#8      B  0.4007715
#9      B  0.1106827
#10     A -0.5558411


means<-aggregate(formula = x~label, data = data, FUN = mean)
means
#  label          x
#1     A 0.27956110
#2     B 0.03327823

for(i in 1:10){
 y[i]=means[which(means[,1]==data[i,1]),2]
}

data<-data.frame(data, y)
data
#   label          x          y
#1      A  1.7150650 0.27956110
#2      B  0.4609162 0.03327823
#3      A -1.2650612 0.27956110
#4      B -0.6868529 0.03327823
#5      B -0.4456620 0.03327823
#6      A  1.2240818 0.27956110
#7      B  0.3598138 0.03327823
#8      B  0.4007715 0.03327823
#9      B  0.1106827 0.03327823
#10     A -0.5558411 0.27956110

您可以使用 data.tabledplyr 包显着提高性能

library(data.table)
setDT(data)[, y := mean(x), label]

library(dplyr)
data %>% 
  group_by(label) %>%
  mutate(y = mean(x))

如果您只有两个标签并且您已经创建了means数据集,您可以在基础中完全向量化它R 使用索引

with(means, c(x[1], x[2]))[(data$label == "B") + 1]

作为旁注,您提到了 merge,因此使用 data.table 您可以对聚合数据进行非常有效的合并,所以让我们在您的 means 数据上进行说明

means <- aggregate(x ~ label, data, mean)

那么你可以简单地做

setkey(setDT(data), label)[means, y := i.x]

这意味着:将 data 转换为 data.table 对象和键 label。在 means 上执行二进制连接,同时仅拉取 x 列并更新 y


另一种选择是执行完全连接

setkey(setDT(means), label) ; setkey(setDT(data), label)
means[data]

您不需要先使用 aggregate 再使用 for 循环。直接用ave就可以了:

data <- transform(data, y = ave(x, label, FUN = mean))

?ave 允许您按组计算 mean 等函数(类似于 aggregate),但不会将数据聚合到每组一行。这意味着输出向量的长度 (y) 与输入向量的长度相同 (在本例中为 x)。