在r中对两个变量进行分组

时间:2017-09-09 18:33:01

标签: r grouping transitive-closure

我有一个如下数据框。

dat <- data.frame(v1=c("a","b","c","c","a","w","f"),
              v2=c("z","a","a","w","p","e","h"))

 v1 v2
1  a  z
2  b  a
3  c  a
4  c  w
5  a  p
6  w  e
7  f  h

我想根据这些字母是否出现在同一行中来添加组列。

   v1 v2  gp
1  a  z   1
2  b  a   1
3  c  a   1
4  c  w   1
5  a  p   1
6  w  e   1
7  f  h   2

我的想法是首先将第一行分配给组1,然后将v1或v2的任何行分配给#34; a&#34;或&#34; z&#34;也将被分配到第1组。

有类似第3行和第4行的情况,其中c被分配给第1组,因为在第3行中,v2是&#34; a&#34;。并且&#34; w&#34;被分配到组1,因为在第4行中,v1是&#34; c&#34;,它先前分配给组1。但我的名单很长,所以我不能继续检查所有&#34;后代&#34;。

我想知道是否有办法对这些字母进行分组,并返回一个包含组号的列表。如下表所示。

letter  gp
a       1
b       1
c       1
e       1
f       2
h       2
w       1
z       1

1 个答案:

答案 0 :(得分:1)

解决此问题的一种方法是将字母视为图形的顶点,并与顶点之间的链接位于同一行。那么你要的是图的连通组件。所有这一切都很容易使用R中的igraph包。

library(igraph)
G = graph_from_edgelist(as.matrix(dat), directed=FALSE)
letters = sort(unique(c(as.character(dat$v1), as.character(dat$v2))))
(gp = components(G)$membership[letters])
a b c e f h p w z 
1 1 1 1 2 2 1 1 1 

如果您想要包含此信息的data.frame

(Groups = data.frame(letters, gp, row.names=NULL))
  letters gp
1       a  1
2       b  1
3       c  1
4       e  1
5       f  2
6       h  2
7       p  1
8       w  1
9       z  1

为了思考其工作原理,可以帮助您查看已创建的图表,并思考如何代表您的问题。 Graph representation