在R中创建data.frame列组合的索引

时间:2013-02-26 20:23:50

标签: r dataframe indexing

此问题与此one有关,但我想使用两个data.frame列的唯一组合创建索引。 所以我的数据结构看起来像这样(dput):

structure(list(avg = c(0.246985988921473, 0.481522354272779, 
0.575400762275067, 0.14651009243539, 0.489308880181752, 0.523678968337178
), i_ID = c("H", "H", "C", "C", "H", "S"), j_ID = c("P", "P", 
"P", "P", "P", "P")), .Names = c("avg", "i_ID", "j_ID"), row.names = 7:12, class = "data.frame")

因此,上述结构的创建索引应如下所示

1
1
2
2
1
3

在示例数据中,列j_ID始终具有值P,但情况并非总是如此。此外,反之亦然(S-P或P-S)组合应该产生相同的指数。

有人知道一个很好的方法来实现这一目标吗?我可以用很多for-loops和if-else命令来做,但那不是很优雅。

2 个答案:

答案 0 :(得分:6)

interaction功能可以正常使用。

foo = structure(list(avg = c(0.246985988921473, 0.481522354272779, 0.575400762275067, 0.14651009243539, 0.489308880181752, 0.523678968337178), i_ID = c("H", "H", "C", "C", "H", "S"), j_ID = c("P", "P", "P", "P", "P", "P")), .Names = c("avg", "i_ID", "j_ID"), row.names = 7:12, class = "data.frame")

foo$idx <- as.integer(interaction(foo$i_ID, foo$j_ID))

> foo
         avg i_ID j_ID idx
7  0.2469860    H    P   2
8  0.4815224    H    P   2
9  0.5754008    C    P   1
10 0.1465101    C    P   1
11 0.4893089    H    P   2
12 0.5236790    S    P   3

啊,我没有仔细阅读。可能有更优雅的解决方案,但您可以使用outer函数以及上下三角形:

# lets assign some test values
x <- c('a', 'b', 'c') 
foo$idx <- c('a b', 'b a', 'b c', 'c b', 'a a', 'b a') 

mat <- outer(x, x, FUN = 'paste') # gives all possible combinations
uppr_ok <- mat[upper.tri(mat, diag=TRUE)]
mat_ok <- mat
mat_ok[lower.tri(mat)] <- mat[upper.tri(mat)]

然后,您可以将mat中找到的索引与mat_ok中找到的索引匹配。

foo$idx <- mat_ok[match(foo$idx, mat)]

但是......我打赌我有一个方便的功能......

答案 1 :(得分:1)

这应该是对@ Justin答案的评论,但这太长了:)

如果您希望索引保留i_ID原件的顺序,可以将interaction()结果分配给变量,然后order levels

x <- interaction(foo$i_ID, foo$j_ID) 
x <- factor(x, levels=levels(x)[order(unique(foo$i_ID))])

foo$idx <- as.integer(x)

给出:

> foo
         avg i_ID j_ID idx
7  0.2469860    H    P   1
8  0.4815224    H    P   1
9  0.5754008    C    P   2
10 0.1465101    C    P   2
11 0.4893089    H    P   1
12 0.5236790    S    P   3