Merge is your friend.
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
Result:
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