Reputation: 13372
I have a list as follows:
mylist <- list(A=seq_len(3)-1, A=seq_len(3)-1, B=seq_len(2)-1, B=seq_len(2)-1)
mylist
$A
[1] 0 1 2
$A
[1] 0 1 2
$B
[1] 0 1
$B
[1] 0 1
meaning that two instances of A
can have the state 0,1,2 and two instances of B
can have the state 0,1.
I would like to produce strings with products of all combinations of all instances, for which the sum of states is (as an example) 1.
I do this by first getting all possible combinations for both A
's and B's
and taking the subset for which the sum is 1.
all.combns <- expand.grid(mylist)
ac <- all.combns[which(rowSums(all.combns)==1),]
unname(apply(ac, 1, function(x)paste(colnames(ac), x, sep="_", collapse=" * ")))
Result is:
"A_1 * A_0 * B_0 * B_0"
"A_0 * A_1 * B_0 * B_0"
"A_0 * A_0 * B_1 * B_0"
"A_0 * A_0 * B_0 * B_1"
First and second string and third and fourth string are he same. My desired result would be:
"2 * A_1 * A_0 * B_0 * B_0"
"2 * A_0 * A_0 * B_1 * B_0"
Is there an elegant way to do this? I thought about adding the rows for both A
's and B
's in all.combns
e.g. cbind(all.combns[,1]+all.combns[,2], all.combns[,3]+all.combns[,3])
and then counting the unique elements with methods described here. However, I do think there must be an easier solution to this, without forming all combinations with expand.grid
.
Upvotes: 0
Views: 1241
Reputation: 11431
Here is one solution. But I guess there is room for more conciseness. I changed your paste
step so the results will be sorted before creating the string as order does not seem to matter in your case. Then use ddply
to count identical cases.
ac <- cmbs[rowSums(cmbs) == 1,]
a <- data.frame(v=apply(ac, 1, function(x)
paste(sort(paste(colnames(ac), x, sep="_")), collapse=" * ")))
d <- ddply(a, .(v), summarise, new = paste(length(v), "*", unique(v)))
d[, "new"]
"2 * A_0 * A_0 * B_0 * B_1" "2 * A_0 * A_1 * B_0 * B_0"
Upvotes: 1