I have 2 data frames. The first has multiple rows the second has a single row. I need to multiply each row of the first frame by the single row of the second frame. The first dataframe is called Costs and looks like this:

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

The second table is named Weights and looks like this:

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

When I multiply them if there is a missing factor in the Weights table I need the corresponding factor in the Costs table needs to become 0.0. The result that I would want would be:

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

After that I will sum the Zone.* columns by row for the total which I already know how to do but if I can skip the intermediate step that would be great. The final result I'm looking for would be:

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

I'm not sure how to do this with dataframes which do not have matching dimensions so any help is greatly appreciated.

有帮助吗?

解决方案

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

其他提示

Here is an option:

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

Yet another possibility:

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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top