Domanda

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.

È stato utile?

Soluzione

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

Altri suggerimenti

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top