如何使用数据框列的子集进行矩阵点积
How to do matrix dot products with a subset of a dataframe's columns
我有一个数据 table 其中几个(但不是全部)列是因子:
df = read.table(text = "
date stock ret DivYield PB ROE
1 2017-06-30 AAPL 0.05 0.050 12 0.10
2 2017-06-30 GOOG 0.25 0.055 11 0.12
3 2017-06-30 MSFT -0.3 0.020 16 0.12
4 2017-07-31 AAPL -.02 0.055 11 0.10
5 2017-07-31 GOOG 0.25 0.050 12 0.10
6 2017-07-31 MSFT 0.01 0.025 14 0.12
", header = TRUE)
我想将最后三列(我的 "factor" 列)乘以权重并将它们相加以计算 z-score:
factor.weights = c(0.3, 0.45, 0.25)
names(factor.weights) = c("DivYield", "PB", "ROE")
结果应如下所示:
date stock ret z.score
1 2017-06-30 AAPL 0.05 5.4400
2 2017-06-30 GOOG 0.25 4.9965
3 2017-06-30 MSFT -0.30 7.2360
4 2017-07-31 AAPL -0.02 4.9915
5 2017-07-31 GOOG 0.25 5.4400
6 2017-07-31 MSFT 0.01 6.3375
我通过
获得了以上
df.answer = data.frame(date = df$date, stock = df$stock, ret = df$ret,
z.score = df$DivYield * factor.weights["DivYield"] +
df$PB * factor.weights["PB"] +
df$ROE * factor.weights["ROE"])
但我需要更聪明的东西,因为我的真实数据有几十列,并且我以编程方式确定 factor.weights
。
关于如何在 select 几列上进行这种矩阵乘法有什么想法吗?
这是一个使用 base
R
的解决方案
> factor.weights = c(0.3, 0.45, 0.25)
> names(factor.weights) = c("DivYield", "PB", "ROE")
>
> # With base R
> df$answer <- as.matrix(df[names(factor.weights)]) %*% factor.weights
> df[, setdiff(colnames(df), setdiff(names(factor.weights), "ret"))]
date stock ret answer
1 2017-06-30 AAPL 0.05 5.4400
2 2017-06-30 GOOG 0.25 4.9965
3 2017-06-30 MSFT -0.30 7.2360
4 2017-07-31 AAPL -0.02 4.9915
5 2017-07-31 GOOG 0.25 5.4400
6 2017-07-31 MSFT 0.01 6.3375
您需要转置 df,然后乘以 factor.weights,然后再次转置结果。如下:
df$z.score <- rowSums(t(t(df[,4:6]) * factor.weights))
我有一个数据 table 其中几个(但不是全部)列是因子:
df = read.table(text = "
date stock ret DivYield PB ROE
1 2017-06-30 AAPL 0.05 0.050 12 0.10
2 2017-06-30 GOOG 0.25 0.055 11 0.12
3 2017-06-30 MSFT -0.3 0.020 16 0.12
4 2017-07-31 AAPL -.02 0.055 11 0.10
5 2017-07-31 GOOG 0.25 0.050 12 0.10
6 2017-07-31 MSFT 0.01 0.025 14 0.12
", header = TRUE)
我想将最后三列(我的 "factor" 列)乘以权重并将它们相加以计算 z-score:
factor.weights = c(0.3, 0.45, 0.25)
names(factor.weights) = c("DivYield", "PB", "ROE")
结果应如下所示:
date stock ret z.score
1 2017-06-30 AAPL 0.05 5.4400
2 2017-06-30 GOOG 0.25 4.9965
3 2017-06-30 MSFT -0.30 7.2360
4 2017-07-31 AAPL -0.02 4.9915
5 2017-07-31 GOOG 0.25 5.4400
6 2017-07-31 MSFT 0.01 6.3375
我通过
获得了以上df.answer = data.frame(date = df$date, stock = df$stock, ret = df$ret,
z.score = df$DivYield * factor.weights["DivYield"] +
df$PB * factor.weights["PB"] +
df$ROE * factor.weights["ROE"])
但我需要更聪明的东西,因为我的真实数据有几十列,并且我以编程方式确定 factor.weights
。
关于如何在 select 几列上进行这种矩阵乘法有什么想法吗?
这是一个使用 base
R
> factor.weights = c(0.3, 0.45, 0.25)
> names(factor.weights) = c("DivYield", "PB", "ROE")
>
> # With base R
> df$answer <- as.matrix(df[names(factor.weights)]) %*% factor.weights
> df[, setdiff(colnames(df), setdiff(names(factor.weights), "ret"))]
date stock ret answer
1 2017-06-30 AAPL 0.05 5.4400
2 2017-06-30 GOOG 0.25 4.9965
3 2017-06-30 MSFT -0.30 7.2360
4 2017-07-31 AAPL -0.02 4.9915
5 2017-07-31 GOOG 0.25 5.4400
6 2017-07-31 MSFT 0.01 6.3375
您需要转置 df,然后乘以 factor.weights,然后再次转置结果。如下:
df$z.score <- rowSums(t(t(df[,4:6]) * factor.weights))