Frage

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.

War es hilfreich?

Lösung

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

Andere Tipps

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top