2014-02-13 6 views
0

У меня есть 2 кадра данных. Первая имеет несколько строк, вторая имеет одну строку. Мне нужно умножить каждую строку первого кадра на одну строку второго кадра. Первый dataframe называется Costs и выглядит следующим образом:R multiply 2 dataframes на основе метки факторов

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 

После этого я подведу Зону * столбцы по строке для общей которой я уже знаю, как это сделать, но если я могу пропустить промежуточный шаг, который был бы большим. , Окончательный результат я ищу будет:

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

Я не знаю, как сделать это с dataframes, которые не имеют соответствующие размеры, так что любая помощь очень ценится.

ответ

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 
+0

Это не делает строго то, что просит ОП, хотя я думаю, что результат тот же, и это намного проще (+1). – BrodieG

+0

@BrodieG true .. хотя я не вижу никакой причины, почему вам нужно/нужно добавить нули к весам, если вы просто собираете их. +1 к вам тоже для того, чтобы точно следовать OP :) –

+0

Чисто действительно! +1. – Henrik

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 
+0

Спасибо за ваш ответ. Я уверен, что мне тоже понадобится это промежуточное состояние, но для этого случая мне просто нужно было суммировать столбцы. Однако, спасибо! –

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