簡體   English   中英

列表到矩陣的復雜重排

[英]Complex rearrangement of list into matrix

對不起,標題含糊不清。 另外,一個例子勝過千言萬語。

我有一個清單:

> lst<-list(A=c("one","two", "three"), B=c("two", "four", "five"), C=c("six", "seven"), D=c("one", "five", "eight"))

> lst
$A
[1] "one"   "two"   "three"

$B
[1] "two"  "four" "five"

$C
[1] "six"   "seven"

$D
[1] "one"   "five"  "eight"

我想重新排列成以下矩陣:

> m
      A B C D
one   1 0 0 1
two   1 1 0 0
three 1 0 0 0
four  0 1 0 0
five  0 1 0 1
six   0 0 1 0
seven 0 0 1 0
eight 0 0 0 1

其中,基本上,每個坐標表示每個列表元素中每個列表值的存在(1)或不存在(0)。

我試着搞亂as.data.frame(),unlist(),table()和melt()的各種組合,沒有成功,所以任何指向正確方向的人都會非常感激。

我想我的最后一招是一個嵌套循環,遍歷列表元素然后將0或1分配給矩陣中的相應坐標,但它看起來過於復雜。

for (...) { 
    for (...) {
        if (...) {
            var <- 1
        } else {
            var <- 0
        }
    }
}

謝謝!

library(reshape2)

table(melt(lst))
#       L1
#value   A B C D
#  one   1 0 0 1
#  three 1 0 0 0
#  two   1 1 0 0
#  five  0 1 0 1
#  four  0 1 0 0
#  seven 0 0 1 0
#  six   0 0 1 0
#  eight 0 0 0 1

這是一個相當手動的方法:

t(table(rep(names(lst), sapply(lst, length)), unlist(lst)))
#        
#         A B C D
#   eight 0 0 0 1
#   five  0 1 0 1
#   four  0 1 0 0
#   one   1 0 0 1
#   seven 0 0 1 0
#   six   0 0 1 0
#   three 1 0 0 0
#   two   1 1 0 0

而且, stack也有效!

table(stack(lst))
#        ind
# values  A B C D
#   eight 0 0 0 1
#   five  0 1 0 1
#   four  0 1 0 0
#   one   1 0 0 1
#   seven 0 0 1 0
#   six   0 0 1 0
#   three 1 0 0 0
#   two   1 1 0 0

更新1

如果你關心行和列順序,你可以在使用table之前明確地factor它們:

A <- stack(lst)
A$values <- factor(A$values, 
                   levels=c("one", "two", "three", "four", 
                            "five", "six", "seven", "eight"))
A$ind <- factor(A$ind, c("A", "B", "C", "D"))
table(A)

更新2:基准!

因為基准測試很有趣......即使我們談論的是微秒...... unlist

set.seed(1)
vec <- sample(3:10, 50, replace = TRUE)
lst <- lapply(vec, function(x) sample(letters, x))
names(lst) <- paste("A", sprintf("%02d", sequence(length(lst))), sep = "")

library(reshape2)
library(microbenchmark)

R2 <- function() table(melt(lst))
S <- function() table(stack(lst))
U <- function() t(table(rep(names(lst), sapply(lst, length)), unlist(lst, use.names=FALSE)))

microbenchmark(R2(), S(), U())
# Unit: microseconds
#  expr       min        lq     median        uq       max neval
#  R2() 36836.579 37521.295 38053.9710 40213.829 45199.749   100
#   S()  1427.830  1473.210  1531.9700  1565.345  3776.860   100
#   U()   892.265   906.488   930.5575   945.326  1261.592   100

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM