向量化创建包含对应于分类变量的均值的向量
Vectorize creation of vector containing means corresponding to categorical variable
Data
包含 label
变量和数字 x
变量,然后我计算 label
指定的组中 x
的平均值(means
对象被创建,然后我们将其用作字典),那么我想
创建包含重复与 label
变量对应的平均值的新向量,下面的示例使用 for()
,我不知道如何对其进行向量化,似乎唯一的可能性是使用 merge
函数,问题是:
merge
是否提供矢量化的好处(我的原始数据集,有几百万个观察值)?
如果不是,那么是否可以对 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.table
或 dplyr
包显着提高性能
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
)。
Data
包含 label
变量和数字 x
变量,然后我计算 label
指定的组中 x
的平均值(means
对象被创建,然后我们将其用作字典),那么我想
创建包含重复与 label
变量对应的平均值的新向量,下面的示例使用 for()
,我不知道如何对其进行向量化,似乎唯一的可能性是使用 merge
函数,问题是:
merge
是否提供矢量化的好处(我的原始数据集,有几百万个观察值)?如果不是,那么是否可以对
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.table
或 dplyr
包显着提高性能
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
)。