element作为列表名称和列表名称作为列表中的元素?

Bio*_*ics 6 r

我有一个向量列表(如下所示).我想知道向量的每个元素在哪个列表元素中.换句话说,我想反转列表以创建一个新的列表,它names取自向量.

这样做的最佳方法是什么?

lst <- list(a=c(2, 3, 6, 10, 15, 17), b=c(4, 6, 9, 7, 6, 4, 3, 10), 
            c=c(9, 2, 1, 4, 3), d=c(3, 6, 17))
lst
$a
[1]  2  3  6 10 15 17

$b
[1]  4  6  9  7  6  4  3 10

$c
[1] 9 2 1 4 3

$d
[1]  3  6 17
Run Code Online (Sandbox Code Playgroud)

我想得到以下答案.

$`1`
[1] "c"

$`10`
[1] "a" "b"

$`15`
[1] "a"

$`17`
[1] "a" "d"

$`2`
[1] "a" "c"

$`3`
[1] "a" "b" "c" "d"

$`4`
[1] "b" "b" "c"

$`6`
[1] "a" "b" "b" "d"

$`7`
[1] "b"

$`9`
[1] "b" "c"
Run Code Online (Sandbox Code Playgroud)

Mat*_*rde 8

这是一个基本的R方式:stackunstack:

unstack(stack(lst), ind ~ values)
# $`1`
# [1] "c"
# 
# $`2`
# [1] "a" "c"
# 
# $`3`
# [1] "a" "b" "c" "d"
# 
# $`4`
# [1] "b" "b" "c"
# 
# $`6`
# [1] "a" "b" "b" "d"
# 
# $`7`
# [1] "b"
# 
# $`9`
# [1] "b" "c"
# 
# $`10`
# [1] "a" "b"
# 
# $`15`
# [1] "a"
# 
# $`17`
# [1] "a" "d"
Run Code Online (Sandbox Code Playgroud)


A5C*_*2T1 6

这是split使用melt"reshape2" 后从基数R使用的方法:

library(reshape2)
x <- melt(lst)
split(x$L1, x$value)
# $`1`
# [1] "c"
# 
# $`2`
# [1] "a" "c"
# 
# $`3`
# [1] "a" "b" "c" "d"
# 
# $`4`
# [1] "b" "b" "c"
# 
# $`6`
# [1] "a" "b" "b" "d"
# 
# $`7`
# [1] "b"
# 
# $`9`
# [1] "b" "c"
# 
# $`10`
# [1] "a" "b"
# 
# $`15`
# [1] "a"
# 
# $`17`
# [1] "a" "d"
Run Code Online (Sandbox Code Playgroud)

同样,在基数R中stack:

x <- stack(lapply(lst, c))
split(as.character(x$ind), x$values)
Run Code Online (Sandbox Code Playgroud)

或者甚至更直接的,如果你使用"lst"而不是"lst":

x <- stack(lst)
split(as.character(x$ind), x$values)
Run Code Online (Sandbox Code Playgroud)

为了详细说明我的评论,我描述的更有效的方式是:

split(rep(names(lst), lapply(lst, nrow)), unlist(lst, use.names = FALSE))
Run Code Online (Sandbox Code Playgroud)

适用于更大的lst,我们得到以下:

fun1 <- function() split(rep(names(lst), lapply(lst, nrow)), unlist(lst, use.names = FALSE))
fun2 <- function() { x <- stack(lapply(lst, c)) ; split(as.character(x$ind), x$values) }
fun3 <- function() { x <- melt(lst) ; split(x$L1, x$value) }
fun4 <- function() unstack(stack(lapply(lst, as.vector)), ind ~ values)

## Make lst much bigger
lst <- unlist(replicate(10000, lst, simplify = FALSE), recursive=FALSE)
names(lst) <- make.unique(names(lst))

library(microbenchmark)

system.time(fun3())
#   user  system elapsed 
# 48.338   0.000  47.643 

microbenchmark(fun1(), fun2(), fun4(), times = 5)
# Unit: milliseconds
#   expr       min        lq   median        uq       max neval
# fun1()  454.5913  456.6793  473.901  555.8954  574.4394     5
# fun2()  922.1282 1028.4972 1034.872 1068.4761 1150.8072     5
# fun4() 1222.5296 1300.0643 1323.253 1339.2037 1421.1546     5
Run Code Online (Sandbox Code Playgroud)