2014-01-22 2 views
1

Я пишу фрагмент кода R и застреваю.Как итеративно выполнить expand.grid в R

Справочная информация (что не является необходимым для решения проблемы): Я вычисляю совместную вероятность путем умножения независимых маргинальных распределений. Маргинальные векторы вероятности генерируются с помощью метода ProbGenerationProcess() итеративно. На каждой итерации он выведет вектор, например.

Iteration 1: 
Color = 
    Blue Green 
    0.2 0.8 

Iteration 2: 
Material = 
    Cotton Silk 
    0.7  0.3 

Iteration 3: 
Country = 
    China  USA 
    0.6  0.4 

...... 

Желаемый результат: Я хочу в результате совместной вероятности быть продуктом каждого отдельного элемента в каждом маргинальной векторе. Формат должен выглядеть так.

Color Material Country Prob 
Blue Cotton  China 0.084 (= 0.2*0.7*0.6) 
Blue Cotton  USA  0.056 (= 0.2*0.7*0.4) 
Blue Silk  China 0.036 (= 0.2*0.3*0.6) 
Blue Silk  USA  .. 
Green Cotton  China .. 
Green Cotton  USA  .. 
...  ...  ...  ... 

Моя реализация: Вот мой код:

joint.names = NULL # data.from store the marginal value names 
joint.probs = NULL # store probabilities. 

for (i in iterations) { 
    marginal = ProbGenerationProcess(VarUniqueToIteration) # output is numeric with names 

    if (is.null(joint.names)) { 
     # initialize the dataframes 
     joint.names = names(marginal) 
     joint.probs = marginal 
    } else { 
     # (my hope:) iteratively populate the joint.names and joint.probs 

     joint.names = expand.grid(joint.names, names(marginal)) 

     expanded.prob = expand.grid(joint.probs, marginal) 
     joint.probs = expanded.prob$Var1 * expanded.prob$Var2 # Row-by-row multiplication. 
    } 
} 

Выход: Joint.probs явкой, чтобы быть всегда правильно, однако, joint.names не совсем работает так, как я разыскивается. После первых двух итераций все работает хорошо. Я получил:

joint.names = 
    Var1 Var2 
1 Blue Cotton 
2 Green Cotton 
3 Blue Silk 
4 Green Silk 
    ... ... 

Start от третьей итерации становится проблематичным:

joint.names = 
    Var1.Var1 Var1.Var2 Var1.Var1.1 Var1.Var2.1 Var2 
1 Blue  Cotton  Blue   Cotton  China 
2 Green  Cotton  Green  Cotton  China 
3 Blue  Silk  Blue   Silk   USA 
4 Green  Silk  Green  Silk   USA 

Я думаю, мой первый вопрос: это самый эффективный способ, чтобы получить результат, что я хотел? Если это так, функция expand.grid() должна использоваться, и как ее инициализировать правильно?

Любая помощь приветствуется!

ответ

2

Слияние - ваш друг.

color <- data.frame(color=c("blue","green"),prob=c(0.2,0.8)) 
material <- data.frame(material=c("cotton","silk"),prob=c(0.7,0.3)) 
country <- data.frame(country=c("china","usa"),prob=c(0.6,0.4)) 

dat <- merge(merge(color[1],material[1]),country[1]) # get names first 

# same as: expand.grid(c("china","usa"),c("cotton","silk"),c("blue","green")) 

dat <- merge(dat, color, by="color") 
dat <- merge(dat, material, by="material") 
dat <- merge(dat, country, by="country") 

dat$joint <- dat$prob.x * dat$prob.y * dat$prob # joint calc 

dat <- dat[-grep("^prob",colnames(dat))] # cleanup extra probs 

Результат:

country material color joint 
1 china cotton blue 0.084 
2 china cotton green 0.336 
3 china  silk blue 0.036 
4 china  silk green 0.144 
5  usa cotton blue 0.056 
6  usa cotton green 0.224 
7  usa  silk blue 0.024 
8  usa  silk green 0.096 
1

Как об этом для simlicity (хотя, если производительность вопрос, может быть, лучше со слиянием)

PROBS<-data.frame(Item=rep(c("Color","Material","Country"),each=2), 
      Value=c("Blue","Green","Cotton","Silk","China","USA"), 
      Prob=c(0.2,0.8,0.7,0.3,0.6,0.4)) 

rownames(PROBS)<-PROBS$Value 

GRID<-expand.grid(by(PROBS,PROBS$Item,function(x)x["Value"])) 

GRID$probs<-apply(GRID,1,function(x)prod(PROBS[c(x),"Prob"])) 

GRID 
# Color Country Material probs 
#1 Blue China Cotton 0.084 
#2 Green China Cotton 0.336 
#3 Blue  USA Cotton 0.056 
#4 Green  USA Cotton 0.224 
#5 Blue China  Silk 0.036 
#6 Green China  Silk 0.144 
#7 Blue  USA  Silk 0.024 
#8 Green  USA  Silk 0.096 
+0

rownames (Probs) <- Probs $ Значение действительно умный! Решение слияния кажется более интуитивным, но спасибо за то, что он показал мне, как правильно использовать expand.grid. –

Смежные вопросы