R基于因子标签乘以2个数据帧

时间:2014-02-13 21:16:53

标签: r dataframe apply mapply

我有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

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分: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