0

我有 2 个数据框。第一个有多行,第二个有单行。我需要将第一帧的每一行乘以第二帧的单行。第一个数据帧被调用Costs,如下所示:

Pounds, Zone.A, Zone.B, Zone.C, Zone.D, Zone.E
5,      10.0,   20.0,   1.00,   23.0,   34.5
10,     20.0,   40.0,   10.0,   34.5,   54.0
15,     40.0,   100.0,  100.0,  67.8,   98.2

第二个表的名称Weights如下所示:

Zone.A, Zone.B, Zone.C
0.5,    0.3,    0.2

当我将它们相乘时,如果表中缺少一个因子,Weights我需要表中的相应因子Costs需要变为0.0. 我想要的结果是:

Pounds, Zone.A, Zone.B, Zone.C, Zone.D, Zone.E
5,      5.0,    6.00,   0.20,   0.0,    0.0
10,     10.0,   12.0,   2.00,   0.0,    0.0
15,     20.0,   30.0,   20.0,   0.0,    0.0

之后,我将按行对 Zone.* 列求和,以获得我已经知道该怎么做的总数,但如果我可以跳过中间步骤,那就太好了。我正在寻找的最终结果是:

Pounds, Total
5,      11.2
10,     24.0
15,     70.0

我不确定如何使用尺寸不匹配的数据框执行此操作,因此非常感谢任何帮助。

4

3 回答 3

3

这是一个选项:

missing.names <- names(Costs[-1])[!names(Costs[-1]) %in% names(Weights)]
Weights[, missing.names] <- do.call(data.frame, as.list(rep(0, length(missing.names))))
cbind(
  Pounds=Costs$Pounds, 
  Total=rowSums(t(t(as.matrix(Costs[2:ncol(Costs)])) * unlist(Weights2[names(Costs[-1])])))
)
#      Pounds Total
# [1,]      5  11.2
# [2,]     10  24.0
# [3,]     15  70.0
于 2014-02-13T21:31:02.180 回答
3
Costs <- read.table(text = "Pounds, Zone.A, Zone.B, Zone.C, Zone.D, Zone.E
5,      10.0,   20.0,   1.00,   23.0,   34.5
10,     20.0,   40.0,   10.0,   34.5,   54.0
15,     40.0,   100.0,  100.0,  67.8,   98.2", header = TRUE, sep = ",")

Weights <- read.table(text = "Zone.A, Zone.B, Zone.C
0.5,    0.3,    0.2", header = TRUE, sep = ",")

CostsMat <- as.matrix(Costs[names(Weights)])

total <- CostsMat %*% matrix(unlist(Weights), ncol = 1)

data.frame(Pounds = Costs$Pounds, Total = total)

##   Pounds Total
## 1      5  11.2
## 2     10  24.0
## 3     15  70.0
于 2014-02-13T21:33:54.643 回答
2

还有一种可能:

library(reshape2)
d1 <- melt(Costs, id.var = "Pounds")
d2 <- melt(Weights)

d1 <- merge(d1, d2, by = "variable", all.x = TRUE)
d1$Total <- with(d1, value.x * value.y) 

aggregate(Total ~ Pounds, data = d1, sum, na.rm = TRUE)

#   Pounds Total
# 1      5  11.2
# 2     10  24.0
# 3     15  70.0
于 2014-02-13T21:40:32.200 回答