我一直在使用 utils 软件包中的出色功能 combn 。该函数创建所有可能的组合,而无需重复Combn description。我将介绍需要使用的函数的一种用法,但未在combn函数中定义它。我想以一个很好的例子来介绍它。但是,我们要实现的实际目标更加复杂,并且需要更多的数据来完成。
我们想玩的游戏只有 3人可以玩。但是,我们是4个人。我们想知道所有可能的玩游戏的人群。参与者的姓名为 Alex , David , John 和 Zoe 。 可能的组合为:
names <- c("Alex","David","John","Zoe")
people.per.group <- 3
combn(names,people.per.group)
#Output
[,1] [,2] [,3] [,4]
[1,] "Alex" "Alex" "Alex" "David"
[2,] "David" "David" "John" "John"
[3,] "John" "Zoe" "Zoe" "Zoe"
但是,我们遇到了问题,因为 Alex与John的关系不佳。因此,我们不想将它们都包含在组中。这样我们就可以为只能选择其中一个的人创建组。
# Alex --> Group 1
# David --> Group 2
# John --> Group 1
# Zoe --> Group 3
only.one.per.group <- c(1,2,1,3)
我正在寻找一个函数,该函数可以使我执行与combn相同的操作,但只能通过变量only.one.per.group限制组合。命名我期待使用var.combn的功能,代码将是:
names <- c("Alex","David","John","Zoe")
only.one.per.group <- c(1,2,1,3)
people.per.group <- 3
var.combn(names,people.per.group,only.one.per.group)
#Output
[,1] [,2]
[1,] "Alex" "David"
[2,] "David" "John"
[3,] "Zoe" "Zoe"
很长一段时间以来,我一直在寻找类似的功能。因此,如果您可以告诉我执行该操作的功能,或以任何突然想到的方式来执行此操作,那将非常有用。
我希望您喜欢这个示例,并且希望获得有关该示例的任何想法。
答案 0 :(得分:0)
这是另一种方式
找到所有可能的组组合:
names <- c("Alex","David","John","Zoe")
x <- expand.grid(names, names, names)
所有可能的组:
Var1 Var2 Var3
1 Alex Alex Alex
2 David Alex Alex
3 John Alex Alex
4 Zoe Alex Alex
5 Alex David Alex
6 David David Alex
7 John David Alex
8 Zoe David Alex
9 Alex John Alex
10 David John Alex
11 John John Alex
12 Zoe John Alex
13 Alex Zoe Alex
14 David Zoe Alex
15 John Zoe Alex
16 Zoe Zoe Alex
17 Alex Alex David
18 David Alex David
19 John Alex David
20 Zoe Alex David
21 Alex David David
22 David David David
23 John David David
24 Zoe David David
25 Alex John David
26 David John David
27 John John David
28 Zoe John David
29 Alex Zoe David
30 David Zoe David
31 John Zoe David
32 Zoe Zoe David
33 Alex Alex John
34 David Alex John
35 John Alex John
36 Zoe Alex John
37 Alex David John
38 David David John
39 John David John
40 Zoe David John
41 Alex John John
42 David John John
43 John John John
44 Zoe John John
45 Alex Zoe John
46 David Zoe John
47 John Zoe John
48 Zoe Zoe John
49 Alex Alex Zoe
50 David Alex Zoe
51 John Alex Zoe
52 Zoe Alex Zoe
53 Alex David Zoe
54 David David Zoe
55 John David Zoe
56 Zoe David Zoe
57 Alex John Zoe
58 David John Zoe
59 John John Zoe
60 Zoe John Zoe
61 Alex Zoe Zoe
62 David Zoe Zoe
63 John Zoe Zoe
64 Zoe Zoe Zoe
找到满足条件的组:
x <- x[which(x[,1] != x[,2]),]
x <- x[which(x[,1] != x[,3]),]
x <- x[which(x[,2] != x[,3]),]
x <- x[-which((x[,1] == "Alex" & x[,2] == "John")),]
x <- x[-which((x[,1] == "Alex" & x[,3] == "John")),]
x <- x[-which((x[,2] == "Alex" & x[,3] == "John")),]
x <- x[-which((x[,2] == "Alex" & x[,1] == "John")),]
x <- x[-which((x[,3] == "Alex" & x[,1] == "John")),]
x <- x[-which((x[,3] == "Alex" & x[,2] == "John")),]
结果:
Var1 Var2 Var3
8 Zoe David Alex
14 David Zoe Alex
20 Zoe Alex David
28 Zoe John David
29 Alex Zoe David
31 John Zoe David
40 Zoe David John
46 David Zoe John
50 David Alex Zoe
53 Alex David Zoe
55 John David Zoe
58 David John Zoe
答案 1 :(得分:0)
这是一个相当紧凑的解决方案,它基于一个假设,即应该从每个组中准确挑选一个人(而且这个假设可能并不总是正确的-从OP中还不清楚)。它利用了一个事实,即应从每个组中选择一个人,因此,如果我们将名称添加到组中并使用expand.grid()
,则可以立即获得解决方案。
DF <- data.frame(names=c("Alex","David","John","Zoe"),
groups=c(1, 2, 1, 3),
stringsAsFactors =FALSE)
expand.grid(lapply(unique(DF$groups), function(i) {DF$names[which(DF$groups==i)]}))
这产生
Var1 Var2 Var3
1 Alex David Zoe
2 John David Zoe
这是您追求的两个组合。稍微紧凑一点的解决方案(仍然使用base R)将是
expand.grid(by(DF, DF$groups, function(x) x$names))
这也许更容易阅读。
它也可以用于更复杂的分组:
DF <- data.frame(names=c("Alex","David","John","Zoe", "Bob", "Charles"),
groups=c(1, 2, 1, 3, 2, 3),
stringsAsFactors =FALSE)
expand.grid(by(DF, DF$groups, function(x) x$names))
产生
Var1 Var2 Var3
1 Alex David Zoe
2 John David Zoe
3 Alex Bob Zoe
4 John Bob Zoe
5 Alex David Charles
6 John David Charles
7 Alex Bob Charles
8 John Bob Charles
现在,如果您想从每个组中选择少于一个,则上面的代码应该包装并套用到combn()
产生的结果上。