有效地将向量列表转换为矩阵

mr.*_*r.T 5 r

我有一个免费大小的向量列表

\n
set.seed(1)\ndat <- lapply(1:10, \\(x) sample(letters, size = sample(1:10,1), replace = T))\n\ndat\n\n[[1]]\n[1] "d" "g" "a" "b" "w" "k" "n" "r" "s"\n\n[[2]]\n[1] "u"\n\n[[3]]\n[1] "j" "v" "n" "j" "g"\n\n[[4]]\n[1] "o" "u" "e" "i" "y" "n" "e" "e" "b"\n\n[[5]]\n [1] "y" "l" "o" "a" "t" "c" "f" "j" "j" "f"\n
Run Code Online (Sandbox Code Playgroud)\n

有哪些方法可以制作像这样的密集矩阵,但效率更高?\n我也想像示例中那样保存列名称

\n
library(arules)\nas(transactions(dat), "matrix")\n\n\n          a     b     c     d     e     f     g     h     i     j     k     l     m\n [1,]  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE\n [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE\n [3,] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE\n [4,] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE\n [5,]  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE\n [6,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE\n [7,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE\n [8,] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE\n [9,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE\n[10,]  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE\n          n     o     r     s     t     u     v     w     x     y     z\n [1,]  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE\n [2,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE\n [3,]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE\n [4,]  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE\n [5,] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE\n [6,] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE\n [7,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE\n [8,] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE\n [9,] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE\n[10,]  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE\n
Run Code Online (Sandbox Code Playgroud)\n

这是 \xd0\xb0rules 包中的示例,未针对我的目的进行优化

\n

Tho*_*ing 6

你可以试试

t(table(stack(setNames(dat, seq_along(dat))))) > 0
Run Code Online (Sandbox Code Playgroud)

这给出了一个表

> t(table(stack(setNames(dat, seq_along(dat))))) > 0
    values
ind      a     b     c     d     e     f     g     h     i     j     k     l
  1   TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
  2  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  3  FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE
  4  FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
  5   TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE
  6  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
  7  FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE
  8  FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE
  9  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  10  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE
    values
ind      m     n     o     r     s     t     u     v     w     x     y     z
  1  FALSE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
  2  FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
  3  FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
  4  FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
  5  FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE
  6  FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE
  7  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE
  8  FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE
  9   TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  10 FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)

一个更短的(并且可能比我以前的stack方法更有效)版本是

> table(rep(seq_along(dat), lengths(dat)), unlist(dat)) > 0

         a     b     c     d     e     f     g     h     i     j     k     l
  1   TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
  2  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  3  FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE
  4  FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
  5   TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE
  6  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
  7  FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE
  8  FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE
  9  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  10  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE

         m     n     o     r     s     t     u     v     w     x     y     z
  1  FALSE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
  2  FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
  3  FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
  4  FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
  5  FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE
  6  FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE
  7  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE
  8  FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE
  9   TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  10 FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)


Mic*_*l M 4

比 @ThomasIsCoding 的好解决方案稍快一些,内存效率更高:

\n
mdummy <- function(dat) {\n  n <- length(dat)\n  vec <- as.factor(unlist(dat, FALSE, FALSE))\n  lvls <- levels(vec)\n  out <- matrix(FALSE, nrow = n, ncol = length(lvls), dimnames = list(NULL, lvls))\n  out[cbind(rep(seq_len(n), lengths(dat)), as.integer(vec))] <- TRUE\n  out\n}\n
Run Code Online (Sandbox Code Playgroud)\n

100 个向量的快速基准测试:

\n
set.seed(1)\ndat <- lapply(1:100, \\(x) sample(letters, size = sample(1:10,1), replace = T))\n\nbench::mark(\n  table(rep(seq_along(dat), lengths(dat)), unlist(dat)) > 0,\n  mdummy(dat),\n  check = FALSE\n)\n\n# expression        min median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time result\n#   1 table()     232\xc2\xb5s  267\xc2\xb5s     3331.     111KB     8.46  1576     4      473ms <NULL>\n#   2 mdummy(dat) 100\xc2\xb5s  118\xc2\xb5s     7104.    45.2KB     6.32  3373     3      475ms <NULL>\n
Run Code Online (Sandbox Code Playgroud)\n