【问题标题】:Create an Index of a combination of data.frame columns in R在 R 中创建 data.frame 列组合的索引
【发布时间】:2013-02-12 11:05:00
【问题描述】:

这个问题与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 循环和 if-else 命令来做到这一点,但这并不是很优雅。

【问题讨论】:

    标签: r dataframe indexing


    【解决方案1】:

    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)]
    

    【讨论】:

    • > 此外,反之亦然(S-P 或 P-S)组合应该产生相同的索引。
    • 我认为这不会遵守 S-P 和 P-S 具有相同索引的另一个约束。
    • 是的,它确实工作得很好,但是正如 Gavin 所说,它并没有给出相同的索引,反之亦然
    【解决方案2】:

    要添加到Justin's answer,如果您希望索引保留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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      • 1970-01-01
      • 1970-01-01
      • 2021-07-30
      • 2016-07-08
      • 1970-01-01
      相关资源
      最近更新 更多