为大量列

时间:2016-08-08 20:20:41

标签: r

我有大量财务数据,包含数百列。我已根据日期清理和排序数据。这是一个简化的例子:

df1 <- data.frame(matrix(vector(),ncol=5, nrow = 4))
colnames(df1) <- c("Date","0.4","0.3","0.2","0.1")
df1[1,] <- c("2000-01-31","0","0","0.05","0.07")
df1[2,] <- c("2000-02-29","0","0.13","0.17","0.09")
df1[3,] <- c("2000-03-31","0.03","0.09","0.21","0.01")
df1[4,] <- c("2004-04-30","0.05","0.03","0.19","0.03")
df1
        Date    0.4    0.3    0.2    0.1
1 2000-01-31      0      0   0.05   0.07
2 2000-02-29      0   0.13   0.17   0.09
3 2000-03-31   0.03   0.09   0.21   0.01
4 2000-04-30   0.05   0.03   0.19   0.03

我将单个权重(基于原始数据的市场价值)指定为列标题,因为我不关心公司名称,我需要权重来计算结果。

我的最终目标是获得:1。加权回报的总和;和2.返回非零时的权重总和。话虽如此,下面是我想得到的结果:

        Date    SWeightedR    SWeights    
1 2000-01-31         0.017         0.3
2 2000-02-29         0.082         0.6
3 2000-03-31         0.082           1
4 2000-04-30          0.07           1

例如,SWeightedR for 2000-01-31 = 0.4x0 + 0.3x0 + 0.2x0.05 + 0.1x0.07,SWeights = 0.2 + 0.1。

我最初的想法是将权重分配给每个列,例如WCol2 <- 0.4,然后使用cbind创建新列,并使用c(as.matrix() %*% )来获取总和。很快我意识到这是不可能的,因为有数百列。任何建议或意见都表示赞赏!

1 个答案:

答案 0 :(得分:2)

这是一个使用矩阵乘法的简单解决方案(正如您自己建议的那样)。

首先,您的数据似乎属于df1[-1] <- lapply(df1[-1], type.convert) 类型,我不确定它是真实数据的真实情况,但我会先将其转换为合适的类型

vec <- as.numeric(names(df1)[-1])

接下来,我们将列名转换为数字类

df1["SWeightedR"] <- as.matrix(df1[, -1]) %*% vec
df1["SWeights"] <- (df1[, -c(1, ncol(df1))] > 0) %*% vec
df1
#         Date  0.4  0.3  0.2  0.1 SWeightedR SWeights
# 1 2000-01-31 0.00 0.00 0.05 0.07      0.017      0.3
# 2 2000-02-29 0.00 0.13 0.17 0.09      0.082      0.6
# 3 2000-03-31 0.03 0.09 0.21 0.01      0.082      1.0
# 4 2004-04-30 0.05 0.03 0.19 0.03      0.070      1.0

最后,我们可以通过两个简单的步骤轻松创建新列。这确实有一个矩阵转换开销,但也许你应该首先使用矩阵。无论哪种方式,这都是完全矢量化的

data.table

或者,您可以先转换为长格式(此处为library(data.table) res <- melt(setDT(df1), id = 1L, variable.factor = FALSE )[, c("value", "variable") := .(as.numeric(value), as.numeric(variable))] res[, .(SWeightedR = sum(variable * value), SWeights = sum(variable * (value > 0))), by = Date] # Date SWeightedR SWeights # 1: 2000-01-31 0.017 0.3 # 2: 2000-02-29 0.082 0.6 # 3: 2000-03-31 0.082 1.0 # 4: 2004-04-30 0.070 1.0 示例),但我认为效率较低,因为这基本上是按行操作

{{1}}