【问题标题】:Condensing 3D data into a Matrix in R将 3D 数据压缩为 R 中的矩阵
【发布时间】:2012-11-18 01:09:30
【问题描述】:

所以我以 130X130 的降序对矩阵进行排序,我想创建一个行名称相同的新矩阵,但每个排序的行列名称是数据所在的位置,而相应列名旁边括号中的数据。它有点像创建一个尺寸为 130x130x2 的 psuedo3D 数组,然后将其压缩成一个没有列名的 130x130 矩阵。这是一个较小的例子。

例子

        A   B   C   D   
    A   14  82  18  50
    B   39  95  27  19
    C   60  40  32  15
    D   70  31  69  31

这就是我想要的

    A   B(82)   D(50)   C(18)   A(14)
    B   B(95)   A(39)   C(27)   D(19)
    C   A(60)   B(40)   C(32)   D(15)
    D   A(70)   C(69)   B(31)   D(31)

我希望这是有道理的!

谢谢!

【问题讨论】:

    标签: r matrix reshape multidimensional-array


    【解决方案1】:

    给你:

    首先,重新创建您的数据:

    x <- read.table(text="
            A   B   C   D   
        A   14  82  18  50
        B   39  95  27  19
        C   60  40  32  15
        D   70  31  69  31", header=TRUE)
    

    两个apply()s,一个paste()和一个matrix(),剩下的就是细节:

    o <- apply(x, 1, order, decreasing=TRUE)
    v <- apply(x, 1, sort, decreasing=TRUE)
    
    matrix(paste(names(x)[o], t(v)), ncol=4, byrow=TRUE)
    
         [,1]   [,2]   [,3]   [,4]  
    [1,] "B 82" "D 50" "C 18" "A 14"
    [2,] "B 95" "A 39" "C 27" "D 19"
    [3,] "A 60" "B 40" "C 32" "D 15"
    [4,] "A 70" "C 69" "B 31" "D 31"
    

    编辑:根据 Jeff Allen 的评论,这可以进一步简化为:

    t(apply(x, 1, function(x){s <- order(x, decreasing=TRUE); paste(names(x)[s], x[s])}))
    
      [,1]   [,2]   [,3]   [,4]  
    A "B 82" "D 50" "C 18" "A 14"
    B "B 95" "A 39" "C 27" "D 19"
    C "A 60" "B 40" "C 32" "D 15"
    D "A 70" "C 69" "B 31" "D 31"
    

    (由于这只有一个apply,它应该会更快。)

    【讨论】:

    • @JeffAllen 根据您的 cmets,我已将其进一步简化为有一个 apply
    • 我喜欢最后一个。您还可以将paste(...) 替换为sprintf("%s(%d)", names(x)[s], x[s]) 以匹配OP 的输出格式。
    【解决方案2】:

    我希望有人会提出一个矢量化的解决方案,但这里有一个选择:

    sortTab <- function(tab){
        for (i in 1:nrow(tab)){
            #Get the order of the elements in the current row
            ord <- order(tab[i,], decreasing=TRUE)
    
            #get the associated column names and values with this ordering      
            res <- paste(colnames(tab)[ord], "(", tab[i,ord], ")", sep="")
    
            #assign back to the data.frame
            tab[i,] <- res
    
        }
        tab
    }
    

    使用您的数据进行测试:

    txt <- textConnection("        A   B   C   D   
        A   14  82  18  50
        B   39  95  27  19
        C   60  40  32  15
        D   70  31  69  31")
    tab <- read.table(txt)
    
    > sortTab(tab)
          A     B     C     D
    A B(82) D(50) C(18) A(14)
    B B(95) A(39) C(27) D(19)
    C A(60) B(40) C(32) D(15)
    D A(70) C(69) B(31) D(31)
    

    【讨论】:

    • 经过进一步审查,这里讨论了我在使用 apply() 时遇到的限制,该限制迫使 for 循环。 stackoverflow.com/questions/2545879/…。我不完全确定这会对这里的表现有所帮助。也许有人可以提出改进建议。
    • 出于兴趣,你指的apply的限制是什么?
    • 我会喜欢以下内容:apply(tab, 1, function(x){x &lt;- paste(order(x)...)})。但是如果不通过引用传递,那是行不通的。
    • 啊,我明白你的意思了。我在编辑的答案中使用了这个想法。
    猜你喜欢
    • 1970-01-01
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多